packages feed

catamorphism 0.6.1.1 → 0.7.0.0

raw patch · 3 files changed

+30/−22 lines, 3 filesdep +QuickCheckPVP ok

version bump matches the API change (PVP)

Dependencies added: QuickCheck

API changes (from Hackage documentation)

Files

catamorphism.cabal view
@@ -1,5 +1,5 @@ name:                catamorphism-version:             0.6.1.1+version:             0.7.0.0 synopsis:            Exposes a Template Haskell function for generating catamorphisms. description:   This module exposes a 'makeCata' function which can create catamorphisms for@@ -71,6 +71,6 @@   main-is:             Tests.hs   hs-source-dirs:      test   ghc-options:         -Wall-  build-depends:       base, catamorphism, hspec+  build-depends:       base, catamorphism, hspec, QuickCheck   other-modules:       Data.Morphism.CataSpec   default-language:    Haskell2010
src/Data/Morphism/Cata.hs view
@@ -62,6 +62,7 @@ > numVars = cataExpr (const 1) (const 0) (+) -} +{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE CPP #-} module Data.Morphism.Cata     ( CataOptions(..)@@ -148,7 +149,10 @@     argTypes = map fixupArgType (conArgTypes c)      fixupArgType t = case typeName t of-                        Just n  -> if n == inputT then VarT resultT else t+                        Just n+                            | n == inputT   -> VarT resultT+                            | n == listName -> AppT ListT (VarT resultT)+                            | otherwise     -> t                         Nothing -> t  -- |The 'makeCata' function creates a catamorphism for the given type.@@ -197,8 +201,11 @@             let patNames = map (\(VarP n) -> n) conPats              let translateArg t arg = case typeName t of-                    Just n -> if n == ty then foldl AppE (VarE funName) (map VarE (conArgNames ++ [arg])) else VarE arg-                    Nothing -> VarE arg+                    Just n+                        | n == ty       -> foldl AppE (VarE funName) (map VarE (conArgNames ++ [arg]))+                        | n == listName -> foldl1 AppE [VarE 'fmap, AppE (VarE funName) (VarE cn), VarE arg]+                        | otherwise     -> VarE arg+                    Nothing             -> VarE arg              let argsWithTypes = zipWith translateArg (conArgTypes c) patNames             let bodyE = foldl AppE (VarE cn) argsWithTypes
test/Data/Morphism/CataSpec.hs view
@@ -1,5 +1,6 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE ScopedTypeVariables #-}  -- GHC 7.10 seems to require KindSignatures for the polymorph folds defined -- below.@@ -10,6 +11,7 @@ module Data.Morphism.CataSpec (main, spec) where  import Test.Hspec+import Test.QuickCheck import Data.Morphism.Cata  import Data.Bool (bool)@@ -21,6 +23,7 @@ data PolymorphSum a = PolymorphSum a data PolymorphProduct a b = PolymorphProduct a b data RegularRecursive a = Cons a (RegularRecursive a) | Empty+data RoseTree a = Node a [RoseTree a]  $(makeCata defaultOptions ''Unit) $(makeCata defaultOptions ''Binary)@@ -28,6 +31,7 @@ $(makeCata defaultOptions ''PolymorphProduct) $(makeCata defaultOptions ''RegularRecursive) $(makeCata defaultOptions { cataName = "binaryFold" } ''Binary)+$(makeCata defaultOptions ''RoseTree)  $(makeCata defaultOptions { cataName = "bool'" } ''Bool) $(makeCata defaultOptions { cataName = "maybe'" } ''Maybe)@@ -65,31 +69,28 @@       length' (Cons () (Cons () (Cons () Empty))) `shouldBe` 3       length' (Cons 'a' (Cons 'b' Empty)) `shouldBe` 2 +    it "handles rose trees" $ do+      let treeSum = roseTree (\x xs -> sum (x:xs)) :: RoseTree Int -> Int+      treeSum (Node 3 []) `shouldBe` 3+      treeSum (Node 0 [Node 1 [Node 2 [], Node 3 []], Node 4 [Node 5 [], Node 6 []], Node 7 [Node 8 [], Node 9 []]]) `shouldBe` 45+   describe "custom options" $     it "allows customizing the function name" $ do       binaryFold 'z' 'o' Zero `shouldBe` 'z'       binaryFold 'z' 'o' One `shouldBe` 'o'    describe "equivalence" $ do-    let checkBinaryFn f g a b x = f a b x `shouldBe` g a b x+    let checkBinaryEquiv f g a b = property (\x -> f a b x == g a b x) -    it "can be used to define bool" $ do-      let check = checkBinaryFn bool bool' "false" "true"-      check False-      check True+    it "can be used to define bool" $+      checkBinaryEquiv bool bool' "false" "true" -    it "can be used to define maybe" $ do-      let check = checkBinaryFn maybe maybe' "<empty>" (++ "!!!")-      check Nothing-      check (Just "Hello")+    it "can be used to define maybe" $+      checkBinaryEquiv maybe maybe' "<empty>" (++ "!!!") -    it "can be used to define either" $ do-      let check = checkBinaryFn either either' show (++ "!!!")-      check (Left True)-      check (Right "Either")+    it "can be used to define either" $+      checkBinaryEquiv either either' (show :: Bool -> String) (++ "!!!") -    it "can be used to define foldr" $ do+    it "can be used to define foldr" $       -- Well, we can get 'foldr', but flipped.-      let check = checkBinaryFn (flip foldr) foldr' (0 :: Int) (\_ acc -> acc + 1)-      check []-      check "Frobnicate"+      checkBinaryEquiv foldr (flip foldr') (\(_ :: Int) (acc :: Int) -> acc + 1) 0