{-# LANGUAGE TemplateHaskell, UndecidableInstances, GADTs #-}
{-# OPTIONS_GHC -fno-warn-incomplete-patterns #-}
module Generics.RepLib.PreludeLib (
EqD,
eqR1,
OrdD,
compareR1,
BoundedD,
minBoundR1,
maxBoundR1,
ShowD,
showsPrecR1
)where
import Generics.RepLib.R
import Generics.RepLib.R1
import Generics.RepLib.RepAux
data EqD a = EqD { eqD :: a -> a -> Bool }
instance Eq a => Sat (EqD a) where
dict = EqD (==)
eqR1 :: R1 EqD a -> a -> a -> Bool
eqR1 Int1 = (==)
eqR1 Char1 = (==)
eqR1 Integer1 = (==)
eqR1 Float1 = (==)
eqR1 Double1 = (==)
eqR1 (Data1 _ cons) = \x y ->
let loop (Con rcd rec : rest) =
case (from rcd x, from rcd y) of
(Just p1, Just p2) -> eqRL1 rec p1 p2
(Nothing, Nothing) -> loop rest
(_,_) -> False
in loop cons
eqR1 r1 = error ("eqR1 undefined for " ++ show r1)
eqRL1 :: MTup EqD l -> l -> l -> Bool
eqRL1 MNil Nil Nil = True
eqRL1 (r :+: rl) (p1 :*: t1) (p2 :*: t2) =
eqD r p1 p2 && eqRL1 rl t1 t2
data OrdD a = OrdD { compareD :: a -> a -> Ordering }
instance Ord a => Sat (OrdD a) where
dict = OrdD { compareD = compare }
lexord :: Ordering -> Ordering -> Ordering
lexord LT _ = LT
lexord EQ ord = ord
lexord GT _ = GT
compareR1 :: R1 OrdD a -> a -> a -> Ordering
compareR1 Int1 = compare
compareR1 Char1 = compare
compareR1 (Data1 _ cons) = \ x y ->
let loop (Con emb rec : rest) =
case (from emb x, from emb y) of
(Just t1, Just t2) -> compareTup rec t1 t2
(Just _ , Nothing) -> LT
(Nothing, Just _ ) -> GT
(Nothing, Nothing) -> loop rest
in loop cons
compareR1 (Abstract1 _) = \_ _ -> EQ
compareR1 r1 = error ("compareR1 not supported for " ++ show r1)
compareTup :: MTup OrdD l -> l -> l -> Ordering
compareTup MNil Nil Nil = EQ
compareTup (x :+: xs) (y :*: ys) (z :*: zs) =
lexord (compareD x y z) (compareTup xs ys zs)
data BoundedD a = BoundedD { minBoundD :: a, maxBoundD :: a }
instance Bounded a => Sat (BoundedD a) where
dict = BoundedD { minBoundD = minBound, maxBoundD = maxBound }
minBoundR1 :: R1 BoundedD a -> a
minBoundR1 Int1 = minBound
minBoundR1 Char1 = minBound
minBoundR1 (Data1 _ (Con emb rec:_)) = to emb (fromTup minBoundD rec)
minBoundR1 r1 = error ("minBoundR1 not supported for " ++ show r1)
maxBoundR1 :: R1 BoundedD a -> a
maxBoundR1 Int1 = maxBound
maxBoundR1 Char1 = maxBound
maxBoundR1 (Data1 _ cons) =
case last cons of (Con emb rec) -> to emb (fromTup maxBoundD rec)
maxBoundR1 r1 = error ("maxBoundR1 not supported for " ++ show r1)
data ShowD a = ShowD { showsPrecD :: Int -> a -> ShowS }
instance Show a => Sat (ShowD a) where
dict = ShowD { showsPrecD = showsPrec }
getFixity :: Emb a b -> Int
getFixity c = case fixity c of
Nonfix -> 0
Infix i -> i
Infixl i -> i
Infixr i -> i
showsPrecR1 :: R1 ShowD a ->
Int ->
a ->
ShowS
showsPrecR1 (Data1 (DT _ _) cons) = \p v ->
case (findCon cons v) of
Val c rec kids ->
case (labels c) of
Just labs -> par $ showString (name c) .
showString "{" .
showRecord rec kids labs .
showString "}"
Nothing -> par $ showString (name c) .
maybespace .
showKids rec kids
where par = showParen (p > p' && conArity > 0)
p' = getFixity c
maybespace = if conArity == (0::Int) then id else (' ':)
conArity = foldr_l (\_ _ i -> 1 + i) 0 rec kids
showKid :: ShowD a -> a -> ShowS
showKid r x = showsPrecD r (p'+1) x
showRecord :: MTup ShowD l -> l -> [String] -> ShowS
showRecord (r :+: MNil) (a :*: Nil) (l : _) = showString l . ('=':) . showKid r a
showRecord (r :+: rs) (a :*: aa) (l : ls) =
showString l . ('=':) . showKid r a . showString (", ") . showRecord rs aa ls
showRecord _ _ _ = error ("Incorrect representation: " ++
"wrong number of labels in record type")
showKids :: MTup ShowD l -> l -> ShowS
showKids MNil Nil = id
showKids (r :+: MNil) (x :*: Nil) = showsPrecD r (p'+1) x
showKids (r :+: cl) (x :*: l) = showsPrecD r (p'+1) x . (' ':) . (showKids cl l)
showsPrecR1 Int1 = showsPrec
showsPrecR1 Char1 = showsPrec
showsPrecR1 Integer1 = showsPrec
showsPrecR1 Float1 = showsPrec
showsPrecR1 Double1 = showsPrec
showsPrecR1 r1 = error ("showsPrecR1 not supported for " ++ show r1)