module Facts.Utility.Templates ( list_to_bijection
, list_to_injection
, list_to_injection_via_pushout
, list_to_injection_via_pullback
) where
import Control.Monad
import Data.Data
import Language.Haskell.TH
import Language.Haskell.TH.Quote
list_to_bijection :: (Data a, Data b) => String -> String -> [(a,b)] -> Q [Dec]
list_to_bijection left_name right_name xs = do
m1 <- list_to_injection left_name xs
m2 <- list_to_injection right_name (adjoint xs)
return $ m1 ++ m2
list_to_injection:: (Data a, Data b) => String -> [(a,b)] -> Q [Dec]
list_to_injection name xs = liftM (\x -> [x]) $ liftM (FunD $ mkName name) (mapM mkClause xs)
where
mkClause (a,b) = do
a_pat <- dataToPatQ (const Nothing) a
b_exp <- dataToExpQ (const Nothing) b
return $ Clause [a_pat] (NormalB b_exp) []
list_to_injection_via_pushout :: (Data a, Data b, Data c) => String -> (b -> c) -> [(a,b)] -> Q [Dec]
list_to_injection_via_pushout name f xs = (list_to_injection name) (fmap (apply_right f) xs)
list_to_injection_via_pullback :: (Data a, Data b, Data c) => String -> (b -> c) -> [(a, b)] -> Q [Dec]
list_to_injection_via_pullback name f xs = (list_to_injection name (adjoint $ fmap (apply_right f) xs))
flip_pair :: (a, b) -> (b, a)
flip_pair = \(a, b) -> (b, a)
adjoint :: [(a,b)] -> [(b,a)]
adjoint = fmap flip_pair
apply_left :: (a -> c) -> (a, b) -> (c, b)
apply_left f (a, b) = (f a, b)
apply_right :: (b -> c) -> (a, b) -> (a, c)
apply_right f (a, b) = (a, f b)