regular-0.2.4: Generic programming library for regular datatypes.

Portabilitynon-portable
Stabilityexperimental
Maintainergenerics@haskell.org

Generics.Regular

Description

Summary: Top-level module for this library. By importing this module, the user is able to use all the generic functionality. The user is only required to provide an instance of Regular for the datatype.

Consider a datatype representing logical expressions:

  data Logic = Var String
             | Logic :->:  Logic  -- implication
             | Logic :<->: Logic  -- equivalence
             | Logic :&&:  Logic  -- and (conjunction)
             | Logic :||:  Logic  -- or (disjunction)
             | Not Logic          -- not
             | T                  -- true
             | F                  -- false

First we import the relevant modules:

 import Generics.Regular
 import Generics.Regular.Functions
 import qualified Generics.Regular.Functions.Show as G
 import qualified Generics.Regular.Functions.Read as G

An instance of Regular can be derived automatically with TH by invoking:

 $(deriveAll ''Logic "PFLogic")
 type instance PF Logic = PFLogic

We define some logic expressions:

 l1, l2, l3 :: Logic
 l1 = Var "p"
 l2 = Not l1
 l3 = l1 :->: l2

And now we can use all of the generic functions. Flattening:

 ex0 :: [Logic]
 ex0 = flattenr (from l3)

 > [Var "p",Not (Var "p")]

Generic equality:

 ex1, ex2 :: Bool
 ex1 = eq l3 l3

 > True


 ex2 = eq l3 l2

 > False

Generic show:

 ex3 :: String
 ex3 = G.show l3

 > "((:->:) (Var \"p\") (Not (Var \"p\")))"

Generic read:

 ex4 :: Logic
 ex4 = G.read ex3

 > Var "p" :->: Not (Var "p")

Value generation:

 ex5, ex6 :: Logic
 ex5 = left

 > Var ""


 ex6 = right

 > F

Folding:

 ex7 :: Bool
 ex7 = fold (alg (\_ -> False)) l3 where
   alg env = (env & impl & (==) & (&&) & (||) & not & True & False)
   impl p q = not p || q

 > True

Unfolding:

 ex8 :: Logic
 ex8 = unfold alg 8 where
   alg :: CoAlgebra Logic Int
   alg n | odd n || n <= 0 = Left ""
         | even n          = Right (Left (n-1,n-2))

 > Var "" :->: (Var "" :->: (Var "" :->: (Var "" :->: Var "")))

Constructor names:

 ex9 = conNames (undefined :: Logic)

 > ["Var",":->:",":<->:",":&&:",":||:","Not","T","F"]

Deep seq:

 ex10 = gdseq (Not (T :->: (error "deep seq works"))) ()

 > *** Exception: deep seq works

Documentation