emgm-0.4: tests/A.hs
-----------------------------------------------------------------------------
-- |
-- Module : A
-- Copyright : (c) 2008 - 2010 Universiteit Utrecht
-- License : BSD3
--
-- Maintainer : generics@haskell.org
--
-- An example type representation.
-----------------------------------------------------------------------------
-- {-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module A where
import Prelude hiding (Read, Show)
import qualified Prelude as P (Read, Show)
import Data.Generics (Data, Typeable)
import Control.Applicative (Alternative, pure)
import Generics.EMGM.Base
import Generics.EMGM.Functions.Collect
import Generics.EMGM.Functions.Everywhere
import Generics.EMGM.Functions.Meta
data A a
= A1 a
| A2 Integer (A a)
| A3 { unA3 :: Double }
| A4 { unA4a :: A a, unA4b :: Int }
| A5 { unA5a :: Char, unA5b :: A a, unA5c :: a }
| A a :^: Float
| (:<>:) { unA7a :: A a, unA7b :: A a }
deriving (P.Show, P.Read, Eq, Ord, Data, Typeable)
infixr 6 :^:
infixl 5 :<>:
type AS a
{- A1 -} = a
{- A2 -} :+: Integer :*: A a
{- A3 -} :+: Double
{- A4 -} :+: A a :*: Int
{- A5 -} :+: Char :*: A a :*: a
{- :^: -} :+: A a :*: Float
{- :<>: -} :+: A a :*: A a
fromA :: A a -> AS a
fromA t = case t of
A1 x1 -> L x1
A2 x1 x2 -> R (L (x1 :*: x2))
A3 x1 -> R (R (L x1))
A4 x1 x2 -> R (R (R (L (x1 :*: x2))))
A5 x1 x2 x3 -> R (R (R (R (L (x1 :*: x2 :*: x3)))))
x1 :^: x2 -> R (R (R (R (R (L (x1 :*: x2))))))
x1 :<>: x2 -> R (R (R (R (R (R (x1 :*: x2))))))
toA :: AS a -> A a
toA s = case s of
L x1 -> A1 x1
R (L (x1 :*: x2)) -> A2 x1 x2
R (R (L x1)) -> A3 x1
R (R (R (L (x1 :*: x2)))) -> A4 x1 x2
R (R (R (R (L (x1 :*: x2 :*: x3))))) -> A5 x1 x2 x3
R (R (R (R (R (L (x1 :*: x2)))))) -> x1 :^: x2
R (R (R (R (R (R (x1 :*: x2)))))) -> x1 :<>: x2
epA :: EP (A a) (AS a)
epA = EP fromA toA
instance HasEP (A a) (AS a) where
epOf _ = epA
conA1 = ConDescr "A1" 1 False Prefix
conA2 = ConDescr "A2" 2 False Prefix
conA3 = ConDescr "A3" 1 True Prefix
conA4 = ConDescr "A4" 2 True Prefix
conA5 = ConDescr "A5" 3 True Prefix
conA6 = ConDescr ":^:" 2 False (Infix RightAssoc 6)
conA7 = ConDescr ":<>:" 2 True (Infix LeftAssoc 5)
lblUnA3 = LblDescr "unA3"
lblUnA4a = LblDescr "unA4a"
lblUnA4b = LblDescr "unA4b"
lblUnA5a = LblDescr "unA5a"
lblUnA5b = LblDescr "unA5b"
lblUnA5c = LblDescr "unA5c"
lblUnA7a = LblDescr "unA7a"
lblUnA7b = LblDescr "unA7b"
instance (Generic g, Rep g a, Rep g Char, Rep g Double, Rep g Float, Rep g Integer, Rep g Int) => Rep g (A a) where
rep = rtype epA
$ rcon conA1 rep
`rsum` rcon conA2 (rep `rprod` rep)
`rsum` rcon conA3 (rlbl lblUnA3 rep)
`rsum` rcon conA4 (rlbl lblUnA4a rep `rprod` rlbl lblUnA4b rep)
`rsum` rcon conA5 (rlbl lblUnA5a rep `rprod` rlbl lblUnA5b rep `rprod` rlbl lblUnA5c rep)
`rsum` rcon conA6 (rep `rprod` rep)
`rsum` rcon conA7 (rlbl lblUnA7a rep `rprod` rlbl lblUnA7b rep)
instance (Generic g) => FRep g A where
frep ra = rtype epA
$ rcon conA1 ra
`rsum` rcon conA2 (rinteger `rprod` frep ra)
`rsum` rcon conA3 (rlbl lblUnA3 rdouble)
`rsum` rcon conA4 (rlbl lblUnA4a (frep ra) `rprod` rlbl lblUnA4b rint)
`rsum` rcon conA5 (rlbl lblUnA5a rchar `rprod` rlbl lblUnA5b (frep ra) `rprod` rlbl lblUnA5c ra)
`rsum` rcon conA6 (frep ra `rprod` rfloat)
`rsum` rcon conA7 (rlbl lblUnA7a (frep ra) `rprod` rlbl lblUnA7b (frep ra))
instance (Generic2 g) => FRep2 g A where
frep2 ra = rtype2 epA epA
$ rcon2 conA1 ra
`rsum2` rcon2 conA2 (rinteger2 `rprod2` frep2 ra)
`rsum2` rcon2 conA3 (rlbl2 lblUnA3 rdouble2)
`rsum2` rcon2 conA4 (rlbl2 lblUnA4a (frep2 ra) `rprod2` rlbl2 lblUnA4b rint2)
`rsum2` rcon2 conA5 (rlbl2 lblUnA5a rchar2 `rprod2` rlbl2 lblUnA5b (frep2 ra) `rprod2` rlbl2 lblUnA5c ra)
`rsum2` rcon2 conA6 (frep2 ra `rprod2` rfloat2)
`rsum2` rcon2 conA7 (rlbl2 lblUnA7a (frep2 ra) `rprod2` rlbl2 lblUnA7b (frep2 ra))
instance (Generic3 g) => FRep3 g A where
frep3 ra = rtype3 epA epA epA
$ rcon3 conA1 ra
`rsum3` rcon3 conA2 (rinteger3 `rprod3` frep3 ra)
`rsum3` rcon3 conA3 (rlbl3 lblUnA3 rdouble3)
`rsum3` rcon3 conA4 (rlbl3 lblUnA4a (frep3 ra) `rprod3` rlbl3 lblUnA4b rint3)
`rsum3` rcon3 conA5 (rlbl3 lblUnA5a rchar3 `rprod3` rlbl3 lblUnA5b (frep3 ra) `rprod3` rlbl3 lblUnA5c ra)
`rsum3` rcon3 conA6 (frep3 ra `rprod3` rfloat3)
`rsum3` rcon3 conA7 (rlbl3 lblUnA7a (frep3 ra) `rprod3` rlbl3 lblUnA7b (frep3 ra))
instance (Alternative f) => Rep (Collect f (A a)) (A a) where
rep = Collect pure
instance (Rep (Everywhere (A a)) a) => Rep (Everywhere (A a)) (A a) where
rep = Everywhere app
where
app f x =
case x of
A1 x1 -> f (A1 (selEverywhere rep f x1))
A2 x1 x2 -> f (A2 (selEverywhere rep f x1) (selEverywhere rep f x2))
A3 x1 -> f (A3 (selEverywhere rep f x1))
A4 x1 x2 -> f (A4 (selEverywhere rep f x1) (selEverywhere rep f x2))
A5 x1 x2 x3 -> f (A5 (selEverywhere rep f x1) (selEverywhere rep f x2) (selEverywhere rep f x3))
x1 :^: x2 -> f (selEverywhere rep f x1 :^: selEverywhere rep f x2)
x1 :<>: x2 -> f (selEverywhere rep f x1 :<>: selEverywhere rep f x2)
instance Rep (Everywhere' (A a)) (A a) where
rep = Everywhere' ($)
v1 = A1 (5 :: Int)
v2 = A2 37 v1
v3 = A3 9999.9999 :: A Float
v4 = A4 v3 79
v5 = A5 'a' v4 5.0
v6 = v5 :^: 0.12345
v7 = v6 :<>: v6