packages feed

unfoldable 0.7 → 0.7.1

raw patch · 3 files changed

+73/−8 lines, 3 filesdep +ghc-prim

Dependencies added: ghc-prim

Files

examples/tree.hs view
@@ -1,3 +1,6 @@+{-# LANGUAGE DeriveGeneric #-}++import GHC.Generics import Control.Applicative import Data.Unfoldable import Data.Unfolder@@ -6,13 +9,14 @@ import System.Random  -data Tree a = Empty | Node (Tree a) a (Tree a) deriving Show+data Tree a = Empty | Node (Tree a) a (Tree a) deriving (Show, Generic1) -instance Unfoldable Tree where-  unfold fa = choose-    [ pure Empty-    , Node <$> unfold fa <*> fa <*> unfold fa-    ]+instance Unfoldable Tree+  -- where+  --   unfold fa = choose+  --     [ pure Empty+  --     , Node <$> unfold fa <*> fa <*> unfold fa+  --     ]      tree7 :: Tree Int tree7 = fromJust $ fromList [0..6]
src/Data/Unfoldable.hs view
@@ -10,7 +10,10 @@ -- -- Class of data structures that can be unfolded. ------------------------------------------------------------------------------{-# LANGUAGE Safe #-}+{-# LANGUAGE CPP, Safe #-}+#ifdef GENERICS+{-# LANGUAGE TypeOperators, DefaultSignatures, FlexibleContexts #-}+#endif module Data.Unfoldable    (   @@ -47,6 +50,10 @@ import Test.QuickCheck.Gen (Gen(..)) import Data.Maybe +#ifdef GENERICS+import GHC.Generics+#endif+ -- | Data structures that can be unfolded. -- -- For example, given a data type@@ -64,9 +71,59 @@ -- -- i.e. it follows closely the instance for 'Traversable', but instead of matching on an input value, -- we 'choose' from a list of all cases.+--+-- Instead of manually writing the `Unfoldable` instance, you can add a @deriving@ `Generic1`+-- to your datatype and declare an `Unfoldable` instance without giving a definition for `unfold`.+--+-- For example the previous example can be simplified to just:+--+-- > {-# LANGUAGE DeriveGeneric #-}+-- >+-- > import GHC.Generics+-- >+-- > data Tree a = Empty | Leaf a | Node (Tree a) a (Tree a) deriving Generic1+-- > +-- > instance Unfoldable Tree class Unfoldable t where   -- | Given a way to generate elements, return a way to generate structures containing those elements.   unfold :: Unfolder f => f a -> f (t a)+  +#ifdef GENERICS+  +  default unfold :: (Generic1 t, GUnfold (Rep1 t), Unfolder f) => f a -> f (t a)+  unfold fa = to1 <$> choose (gunfold fa)+  +class GUnfold r where+  gunfold :: Unfolder f => f a -> [f (r a)]+  +instance GUnfold V1 where+  gunfold _ = []+  +instance GUnfold U1 where+  gunfold _ = [pure U1]++instance GUnfold Par1 where+  gunfold fa = [Par1 <$> fa]++instance Unfoldable f => GUnfold (Rec1 f) where+  gunfold fa = [Rec1 <$> unfold fa]++instance (Bounded c, Enum c) => GUnfold (K1 i c) where+  gunfold _ = [K1 <$> boundedEnum]++instance GUnfold f => GUnfold (M1 i c f) where+  gunfold fa = map (M1 <$>) (gunfold fa)+  +instance (GUnfold f, GUnfold g) => GUnfold (f :+: g) where+  gunfold fa = map (L1 <$>) (gunfold fa) ++ map (R1 <$>) (gunfold fa)++instance (GUnfold f, GUnfold g) => GUnfold (f :*: g) where+  gunfold fa = liftA2 (:*:) <$> gunfold fa <*> gunfold fa++instance (GUnfold f, GUnfold g) => GUnfold (f :.: g) where+  gunfold fa = map (Comp1 <$>) (gunfold (choose (gunfold fa)))++#endif  -- | Unfold the structure, always using @()@ as elements. unfold_ :: (Unfoldable t, Unfolder f) => f (t ())
unfoldable.cabal view
@@ -1,5 +1,5 @@ Name:                 unfoldable-Version:              0.7+Version:              0.7.1 Synopsis:             Class of data structures that can be unfolded. Description:          Just as there's a Foldable class, there should also be an Unfoldable class.                        .@@ -39,6 +39,10 @@     , transformers >= 0.3 && < 0.4     , random       >= 1.0 && < 1.1     , QuickCheck   >= 2.4 && < 2.6++  if impl(ghc >= 7.6)+    cpp-options:   -DGENERICS+    build-depends: ghc-prim >= 0.2  source-repository head   type:     git