control-monad-omega 0.3.3 → 0.3.4
raw patch · 4 files changed
+43/−3 lines, 4 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- Control/Monad/Omega.hs +7/−2
- control-monad-omega.cabal +1/−1
- test/Properties.hs +31/−0
CHANGELOG.md view
@@ -1,3 +1,7 @@+# 0.3.4++* Fix a regression in 0.3.3, which made `liftA2` too strict.+ # 0.3.3 * Speed up `Applicative` / `Alternative` / `MonadPlus` instances.
Control/Monad/Omega.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -Wno-unrecognised-pragmas #-} {-# HLINT ignore "Avoid restricted function" #-} ----------------------------------------------@@ -110,8 +111,12 @@ pure = Omega . (:[]) liftA2 f (Omega xs) = Omega . go [] . runOmega where- go initYs [] = concatMap (flip (zipWith f) initYs) (tails xs)- go initYs (y : ys) = zipWith f xs initYs ++ go (y : initYs) ys+ go [] = \case+ [] -> []+ y : ys -> go [y] ys+ go initYs = (zipWith f xs initYs ++) . \case+ [] -> concatMap (flip (zipWith f) initYs) (drop 1 (tails xs))+ y : ys -> go (y : initYs) ys instance Applicative.Alternative Omega where empty = Omega []
control-monad-omega.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.0 name: control-monad-omega-version: 0.3.3+version: 0.3.4 license: PublicDomain maintainer: lrpalmer@gmail.com author: Luke Palmer
test/Properties.hs view
@@ -29,5 +29,36 @@ let f x y = x * 10 + y in runOmega (liftA2 f (each xs) (each ys)) === runOmega (join (each (map (\x -> each (map (\y -> f x y) ys)) xs)))++ , testProperty "liftA2 (,) undefined []" $ once $+ runOmega (liftA2 (,) undefined (each [])) === ([] :: [((), ())])+ , testProperty "liftA2 (,) (1 : undefined) (1 : undefined)" $ once $+ take 1 (runOmega (liftA2 (,) (each (1 : undefined)) (each (1 : undefined)))) === [(1, 1)]+ , adjustOption (min (mkTimeout 1000000)) $+ testProperty "enumerate arithGrammar" $ once $+ take 10 (runOmega (enumerate arithGrammar)) ===+ ["0","1","0+0","0*0","0+1","(0)","1+0","0*1","0+0*0","00"] ] +-- From https://web.archive.org/web/20140823135714/http://lukepalmer.wordpress.com/2008/05/02/enumerating-a-context-free-language/++data Symbol a+ = Terminal a+ | Nonterminal [[Symbol a]] -- a disjunction of juxtapositions++enumerate :: Symbol a -> Omega [a]+enumerate (Terminal a) = return [a]+enumerate (Nonterminal alts) = do+ alt <- each alts -- for each alternative+ rep <- mapM enumerate alt -- enumerate each symbol in the sequence+ return $ concat rep -- and concatenate the results++arithGrammar :: Symbol Char+arithGrammar = s+ where+ s = Nonterminal [[add]]+ add = Nonterminal [[mul], [add, Terminal '+', mul]]+ mul = Nonterminal [[term], [mul, Terminal '*', term]]+ term = Nonterminal [[number], [Terminal '(', s, Terminal ')']]+ digit = Nonterminal $ map (map Terminal . show) [0..9]+ number = Nonterminal [[digit], [digit, number]]