hw-balancedparens-0.2.1.0: gen/HaskellWorks/Data/BalancedParens/Gen.hs
{-# LANGUAGE TupleSections #-}
module HaskellWorks.Data.BalancedParens.Gen
( BP(..)
, count
, bpBools
, showBps
, storableVector
, bpParensSeq
, vector
, vec2
, randomRmm
, randomRmm2
) where
import Data.Coerce
import Data.Semigroup ((<>))
import Data.Word
import HaskellWorks.Data.BalancedParens.Internal.ParensSeq (ParensSeq)
import HaskellWorks.Data.Positioning
import Hedgehog
import qualified Data.Vector as DV
import qualified Data.Vector.Storable as DVS
import qualified HaskellWorks.Data.BalancedParens.Internal.ParensSeq as PS
import qualified HaskellWorks.Data.BalancedParens.RangeMinMax as RMM
import qualified HaskellWorks.Data.BalancedParens.RangeMinMax2 as RMM2
import qualified Hedgehog.Gen as G
import qualified Hedgehog.Range as R
count :: MonadGen m => Range Count -> m Count
count r = coerce <$> G.word64 (coerce <$> r)
data LR a = L a Int | R a Int deriving (Eq, Show)
newtype BP = BP [Bool] deriving Eq
showBps :: [Bool] -> String
showBps = fmap fromBool
where fromBool True = '('
fromBool False = ')'
bpBools' :: MonadGen m => Int -> (Int, [Bool], [Bool], Int) -> m [Bool]
bpBools' n (ln, lt, rt, rn) = if n <= 0
then return (reverse lt <> rt)
else if ln - rn >= n
then return (reverse lt <> replicate n False <> rt)
else if rn - ln >= n
then return (reverse lt <> replicate n True <> rt)
else do
decision <- case (ln, rn) of
(0, 0) -> G.element [L '(' 1, R ')' 1]
(0, _) -> G.element [L '(' 1, R '(' (-1), R ')' 1]
(_, 0) -> G.element [L '(' 1, L ')' (-1), R ')' 1]
_ -> G.element [L '(' 1, R ')' 1]
case decision of
L p d -> bpBools' (n - 1) (ln + d, toBool p:lt, rt, rn )
R p d -> bpBools' (n - 1) (ln , lt, toBool p:rt, rn + d)
where toBool '(' = True
toBool _ = False
bpBools :: MonadGen m => Range Int -> m [Bool]
bpBools r = do
n <- G.int r
bpBools' (n * 2) (0, [], [], 0)
bpParensSeq :: MonadGen m => Range Int -> m ParensSeq
bpParensSeq = fmap PS.fromBools . bpBools
storableVector :: (MonadGen m, DVS.Storable a) => Range Int -> m a -> m (DVS.Vector a)
storableVector r g = DVS.fromList <$> G.list r g
vector :: MonadGen m => Range Int -> m a -> m (DV.Vector a)
vector r g = DV.fromList <$> G.list r g
vec2 :: MonadGen m => m a -> m (a, a)
vec2 g = (,) <$> g <*> g
randomRmm :: MonadGen m => Range Int -> m (RMM.RangeMinMax (DVS.Vector Word64))
randomRmm r = do
v <- storableVector (fmap (64 *) r) (G.word64 R.constantBounded)
return (RMM.mkRangeMinMax v)
randomRmm2 :: MonadGen m => Range Int -> m (RMM2.RangeMinMax2 (DVS.Vector Word64))
randomRmm2 r = do
v <- storableVector (fmap (64 *) r) (G.word64 R.constantBounded)
return (RMM2.mkRangeMinMax2 v)