{-# LANGUAGE FlexibleInstances #-}

module HaskellWorks.Data.BalancedParens.FindOpen
  ( FindOpen(..)
  ) where

import Data.Word
import HaskellWorks.Data.BalancedParens.FindOpenN
import HaskellWorks.Data.BalancedParens.OpenAt
import HaskellWorks.Data.Bits.BitShown
import HaskellWorks.Data.Naive
import HaskellWorks.Data.Positioning

import qualified Data.Vector.Storable as DVS

class FindOpen v where
  findOpen :: v -> Count -> Maybe Count

instance (FindOpen a) => FindOpen (BitShown a) where
  findOpen :: BitShown a -> Count -> Maybe Count
findOpen = a -> Count -> Maybe Count
forall v. FindOpen v => v -> Count -> Maybe Count
findOpen (a -> Count -> Maybe Count)
-> (BitShown a -> a) -> BitShown a -> Count -> Maybe Count
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BitShown a -> a
forall a. BitShown a -> a
bitShown
  {-# INLINE findOpen #-}

instance FindOpen [Bool] where
  findOpen :: [Bool] -> Count -> Maybe Count
findOpen [Bool]
v Count
p = if [Bool]
v [Bool] -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else [Bool] -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  [Bool]
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (DVS.Vector Word8) where
  findOpen :: Vector Word8 -> Count -> Maybe Count
findOpen Vector Word8
v Count
p = if Vector Word8
v Vector Word8 -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else Vector Word8 -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Vector Word8
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (DVS.Vector Word16) where
  findOpen :: Vector Word16 -> Count -> Maybe Count
findOpen Vector Word16
v Count
p = if Vector Word16
v Vector Word16 -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt` Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else Vector Word16 -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Vector Word16
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (DVS.Vector Word32) where
  findOpen :: Vector Word32 -> Count -> Maybe Count
findOpen Vector Word32
v Count
p = if Vector Word32
v Vector Word32 -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else Vector Word32 -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Vector Word32
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (DVS.Vector Word64) where
  findOpen :: Vector Count -> Count -> Maybe Count
findOpen Vector Count
v Count
p = if Vector Count
v Vector Count -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt` Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else Vector Count -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Vector Count
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen Word8 where
  findOpen :: Word8 -> Count -> Maybe Count
findOpen Word8
v Count
p = if Word8
v Word8 -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else Word8 -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Word8
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen Word16 where
  findOpen :: Word16 -> Count -> Maybe Count
findOpen Word16
v Count
p = if Word16
v Word16 -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else Word16 -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Word16
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen Word32 where
  findOpen :: Word32 -> Count -> Maybe Count
findOpen Word32
v Count
p = if Word32
v Word32 -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else Word32 -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Word32
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen Word64 where
  findOpen :: Count -> Count -> Maybe Count
findOpen Count
v Count
p = if Count
v Count -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else Count -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Count
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}

instance FindOpen (Naive Word64) where
  findOpen :: Naive Count -> Count -> Maybe Count
findOpen Naive Count
v Count
p = if Naive Count
v Naive Count -> Count -> Bool
forall v. OpenAt v => v -> Count -> Bool
`openAt`  Count
p then Count -> Maybe Count
forall a. a -> Maybe a
Just Count
p else Naive Count -> Count -> Count -> Maybe Count
forall v. FindOpenN v => v -> Count -> Count -> Maybe Count
findOpenN  Naive Count
v Count
0 (Count
p Count -> Count -> Count
forall a. Num a => a -> a -> a
- Count
1)
  {-# INLINE findOpen #-}