Safe Haskell | None |
---|---|
Language | Haskell2010 |
The module Data.Thorn.Fold.
- unfixdata :: TypeQ -> String -> (String -> String) -> [Name] -> DecsQ
- autofold :: TypeQ -> TypeQ -> ExpQ
- autofoldtype :: TypeQ -> TypeQ -> TypeQ
- autofolddec :: String -> TypeQ -> TypeQ -> DecsQ
- autounfold :: TypeQ -> TypeQ -> ExpQ
- autounfoldtype :: TypeQ -> TypeQ -> TypeQ
- autounfolddec :: String -> TypeQ -> TypeQ -> DecsQ
- unfixdataMutual :: [(TypeQ, String, String -> String, [Name])] -> DecsQ
- autofoldMutual :: [(TypeQ, TypeQ)] -> Int -> ExpQ
- autofoldtypeMutual :: [(TypeQ, TypeQ)] -> Int -> TypeQ
- autofolddecMutual :: String -> [(TypeQ, TypeQ)] -> Int -> DecsQ
- autounfoldMutual :: [(TypeQ, TypeQ)] -> Int -> ExpQ
- autounfoldtypeMutual :: [(TypeQ, TypeQ)] -> Int -> TypeQ
- autounfolddecMutual :: String -> [(TypeQ, TypeQ)] -> Int -> DecsQ
- modifynameUf :: String -> String
- autoin :: TypeQ -> TypeQ -> ExpQ
- autoout :: TypeQ -> TypeQ -> ExpQ
- autohylo :: TypeQ -> ExpQ
- autoinMutual :: [(TypeQ, TypeQ)] -> Int -> ExpQ
- autooutMutual :: [(TypeQ, TypeQ)] -> Int -> ExpQ
- autohyloMutual :: [TypeQ] -> Int -> ExpQ
Folding and Unfolding
Thorn generates folds and unfolds from various kinds of recursive datatypes, including mutually recursive ones.
:: TypeQ |
|
-> String |
|
-> (String -> String) |
|
-> [Name] |
|
-> DecsQ | declaration of a nonrecursive datatype whose fixpoint is |
unfixdata t n f ds
provides a declaration of a nonrecursive datatype whose fixpoint is the recursive type t
, with a deriving declaration with names ds
.
:: TypeQ |
|
-> TypeQ |
|
-> ExpQ | fold with a type |
autofold u t
provides a fold for the recursive type t
.
autofoldtype :: TypeQ -> TypeQ -> TypeQ Source
autofoldtype u t
provides the type of $(
, that is, autofold
u t)(u x0 .. xn a -> a) -> (t x0 .. xn -> a)
.
autofolddec :: String -> TypeQ -> TypeQ -> DecsQ Source
autofolddec s u t
provides a declaration of a fold for the recursive type t
with the name s
, with a type signature.
:: TypeQ |
|
-> TypeQ |
|
-> ExpQ | unfold with a type |
autounfold u t
provides an unfold for the recursive type t
.
autounfoldtype :: TypeQ -> TypeQ -> TypeQ Source
autounfoldtype u t
provides the type of $(
, that is, autounfold
u t)(a -> u x0 .. xn a) -> (a -> t x0 .. xn)
.
autounfolddec :: String -> TypeQ -> TypeQ -> DecsQ Source
autounfolddec s u t
provides a declaration of an unfold for the recursive type t
with the name s
, with a type signature.
Mutual Recursion
:: [(TypeQ, String, String -> String, [Name])] |
|
-> DecsQ | declarations of datatypes |
Mutually recursive version of unfixdata
. Note that
unfixdata
t s f ds =unfixdataMutual
[(t,s,f,ds)]
:: [(TypeQ, TypeQ)] |
|
-> Int |
|
-> ExpQ | fold with a type |
autofoldMutual uts k
provides a fold for the mutually recursive type tk
.
autofoldtypeMutual :: [(TypeQ, TypeQ)] -> Int -> TypeQ Source
autofoldtypeMutual uts k
provides the type of $(
, that is, autofoldMutual
uts k)(u0 x0 .. xm a0 .. an -> a0) -> .. -> (un x0 .. xm a0 .. an -> an) -> (tk x0 .. xm -> ak)
.
autofolddecMutual :: String -> [(TypeQ, TypeQ)] -> Int -> DecsQ Source
autofolddecMutual s uts k
provides a declaration of a fold for the mutually recursive type tk
with the name s
, with a type signature.
:: [(TypeQ, TypeQ)] |
|
-> Int |
|
-> ExpQ | unfold with a type |
autounfoldMutual uts k
provides an unfold for the mutually recursive type tk
.
autounfoldtypeMutual :: [(TypeQ, TypeQ)] -> Int -> TypeQ Source
autounfoldtypeMutual uts k
provides the type of $(
, that is, autounfoldMutual
uts k)(a0 -> u0 x0 .. xm a0 .. an) -> .. -> (an -> un x0 .. xm a0 .. an) -> (ak -> tk x0 .. xm)
.
autounfolddecMutual :: String -> [(TypeQ, TypeQ)] -> Int -> DecsQ Source
autounfolddecMutual s uts k
provides a declaration of an unfold for the mutually recursive type tk
with the name s
, with a type signature.
Helper Function
modifynameUf :: String -> String Source
Use this function to designate how to convert the name of data constructors for unfixdata
.
modifynameUf "Hello" == "UfHello" modifynameUf ":***" == ":&***"
Note that
modifynameUf
==modifyname
("Uf","") ("&","")
Primitive Functions
:: [(TypeQ, TypeQ)] |
|
-> Int |
|
-> ExpQ | function with a type |
Mutually recursive version of autoin
.
:: [(TypeQ, TypeQ)] |
|
-> Int |
|
-> ExpQ | function with a type |
Mutually recursive version of autoout
.
:: [TypeQ] |
|
-> Int |
|
-> ExpQ | function with a type |
Mutually recursive version of autohylo
.
Examples
Basic
It's a piece of cake.
Note tht foldlist
is analogous with foldr
and unfoldlist
with unfoldr
.
data List a = Nil | a :* (List a) deriving Show unfixdata [t|List|] "UfList" modifynameUf [''Show] -- data UfList a self = UfNil | a :&* self deriving Show autofolddec "foldlist" [t|UfList|] [t|List|] autounfolddec "unfoldlist" [t|UfList|] [t|List|] fib :: List Int fib = unfoldlist go (0,1) -- 1 :* (1 :* (2 :* (3 :* (5 :* (8 :* (13 :* Nil)))))) where go :: (Int,Int) -> UfList Int (Int,Int) go (a,b) | b > 20 = UfNil | otherwise = b :&* (b,a+b) fibsum :: Int fibsum = foldlist add fib -- 33 where add :: UfList Int Int -> Int add UfNil = 0 add (m :&* n) = m+n normalfib :: [Int] normalfib = foldlist go fib -- [1,1,2,3,5,8,13] where go :: UfList a [a] -> [a] go UfNil = [] go (a :&* as) = a:as
Mutual Recursion
It also works for mutual recursion.
It's just an extension of simple recursion. Take it easy.
data Rose x = x :-< (Forest x) deriving Show data Forest x = F [Rose x] deriving Show unfixdataMutual [([t|Rose|],"UfRose",modifynameUf,[''Show]), ([t|Forest|],"UfForest",modifynameUf,[''Show])] -- data UfRose x rose forest = x :&-< forest deriving Show -- data UfForest x rose forest = UfF [rose] deriving Show autofolddecMutual "foldrose" [([t|UfRose|],[t|Rose|]),([t|UfForest|],[t|Forest|])] 0 -- foldrose :: (UfRose x a b -> a) -> (UfForest x a b -> b) -> Rose x -> a -- foldrose = ... autounfolddecMutual "unfoldrose" [([t|UfRose|],[t|Rose|]),([t|UfForest|],[t|Forest|])] 0 -- unfoldrose :: (a -> UfRose x a b) -> (b -> UfForest x a b) -> a -> Rose x -- unfoldrose = ... rose :: Rose Int rose = unfoldrose gorose goforest 0 -- 0 :-< F [1 :-< F [3 :-< F [],4 :-< F []],2 :-< F [5 :-< F [],6 :-< F []]] where gorose :: Int -> UfRose Int Int Int gorose n | n > 2 = n :&-< (-1) | otherwise = n :&-< n goforest :: Int -> UfForest Int Int Int goforest (-1) = UfF [] goforest n = UfF [n*2+1,n*2+2] showrose :: Show x => Rose x -> String showrose = unlines . foldrose gorose goforest where gorose :: Show x => UfRose x [String] [String] -> [String] gorose (x :&-< ls) = [show x] ++ ls goforest :: UfForest x [String] [String] -> [String] goforest (UfF []) = [] goforest (UfF lss) = concatMap hang (init lss) ++ hang' (last lss) hang ls = ["|"] ++ ["+--" ++ head ls] ++ map ("| "++) (tail ls) hang' ls = ["|"] ++ ["+--" ++ head ls] ++ map (" "++) (tail ls) shownrose :: String shownrose = showrose rose -- 0 -- | -- +--1 -- | | -- | +--3 -- | | -- | +--4 -- | -- +--2 -- | -- +--5 -- | -- +--6