--
import Array
import IOExts
import ST
import List(findIndices)
-- Higher order types are type constructors
data Tuple x y = Tuple (x,y)
-- Even Higher Order Types
-- type constructors that take type constructors as arguments
data Tree t a = Tip a | Node (t (Tree t a))
t1 = Node [Tip 3, Tip 0]
data Bin x = Two x x
t2 = Node (Two(Tip 5) (Tip 21))
-- Built in higher order types and their notation
type Arrow = (->) Int Int
type List = [] Int
type Pair = (,) Int Int
type Triple = (,,) Int Int Int
-- Type classes over type constructors
{- Defined in Prelude, so must be commented out here
class Functor f where
fmap :: (a -> b) -> (f a -> f b)
-- Functor Laws
-- map id = id
-- map (f.g) = map f . map g
-}
-- Examples
data BinTree a = Leaf a | Branch (BinTree a) (BinTree a)
instance Functor BinTree where
fmap f (Leaf x) = Leaf (f x)
fmap f (Branch x y) = Branch (fmap f x) (fmap f y)
instance Functor ((,) a) where
fmap f (x,y) = (x, f y)
data Count x = C(x,Int)
instance Functor Count where
fmap f (C(x,y)) = C(f x, y)
{- Prelude defined instances
instance Functor [] where
fmap f [] = []
fmap f (x:xs) = f x : fmap f xs
instance Functor Maybe where
fmap f Nothing = Nothing
fmap f (Just x) = Just (f x)
-}
--------------------------------------------------
-- Another higher order Class -- Monad
{- Class Monad - predefined in prelude
class Monad m where
(>>=) :: m a -> (a -> m b) -> m b
(>>) :: m a -> m b -> m b
return :: a -> m a
fail :: String -> m a
p >> q = p >>= \ _ -> q
fail s = error s
-}
{- Predefined instances
instance Monad [ ] where
(x:xs) >>= f = f x ++ (xs >>= f)
[] >>= f = []
return x = [x]
instance Monad Maybe where
Just x >>= k = k x
Nothing >>= k = Nothing
return = Just
-}
-- Example of use in the Maybe Monad
find :: Eq a => a -> [(a,b)] -> Maybe b
find x [] = Nothing
find x ((y,a):ys) = if x == y then Just a else find x ys
test a c x =
do { b <- find a x; return (c+b) }
--------------------------------------------
-- Multiparameter type classes
class Same ref where
same :: ref a -> ref a -> Bool
class (Monad m,Same ref) => Mutable ref m where
put :: ref a -> a -> m ()
get :: ref a -> m a
new :: a -> m (ref a)
-- A couple of instances
instance Mutable (STRef a) (ST a) where
put = writeSTRef
get = readSTRef
new = newSTRef
instance Same (STRef a) where
same x y = x==y
instance Mutable IORef IO where
new = newIORef
get = readIORef
put = writeIORef
instance Same IORef where
same x y = x==y
--------------------------------------------------
-- Example use Unification
data (Mutable ref m ) =>
Type ref m =
Tvar (ref (Maybe (Type ref m)))
| Tgen Int
| Tarrow (Type ref m) (Type ref m)
| Ttuple [Type ref m]
| Tcon String [Type ref m]
-- run down a chain of Type TVar references making them all point
-- to the last item in the chain
prune :: (Monad a, Mutable b a) => Type b a -> a (Type b a)
prune (typ @ (Tvar ref)) =
do { m <- get ref
; case m of
Just t -> do { newt <- prune t
; put ref (Just newt)
; return newt
}
Nothing -> return typ}
prune x = return x
occursIn :: Mutable ref m => ref (Maybe (Type ref m)) -> Type ref m -> m Bool
occursIn ref1 t =
do { t2 <- prune t
; case t2 of
Tvar ref2 -> return (same ref1 ref2)
Tgen n -> return False
Tarrow a b ->
do { x <- occursIn ref1 a
; if x then return True
else occursIn ref1 b
}
Ttuple xs ->
do { bs <- sequence(map (occursIn ref1) xs)
; return(any id bs)
}
Tcon c xs ->
do { bs <- sequence(map (occursIn ref1) xs)
; return(any id bs)
}
}
unify :: Mutable ref m =>
(Type ref m -> Type ref m -> m [String]) ->
Type ref m -> Type ref m -> m [String]
unify occursAction x y =
do { t1 <- prune x
; t2 <- prune y
; case (t1,t2) of
(Tvar r1,Tvar r2) ->
if same r1 r2
then return []
else do { put r1 (Just t2); return []}
(Tvar r1,_) ->
do { b <- occursIn r1 t2
; if b then occursAction t1 t2
else do { put r1 (Just t2); return [] }
}
(_,Tvar r2) -> unify occursAction t2 t1
(Tgen n,Tgen m) -> if n==m then return [] else return ["generic error"]
(Tarrow a b,Tarrow x y) ->
do { e1 <- unify occursAction a x
; e2 <- unify occursAction b y
; return (e1 ++ e2)
}
(_,_) -> return ["shape match error"]
}
--------------------------------------------
class Name term name where
isName :: term -> Maybe name
fromName :: name -> term
type Var = String
data Term0 =
Add0 Term0 Term0
| Const0 Int
| Lambda0 Var Term0
| App0 Term0 Term0
| Var0 Var
instance Name Term0 Var where
isName (Var0 s) = Just s
isName _ = Nothing
fromName s = Var0 s
-----------------------------------------------
-- Another multi parameter type Class
class Gensym monad name where
newGensym :: monad (String -> monad name)
gensym :: String -> monad name
--------------------------------------------
-- Yet another
class Mult a b c where
times :: a -> b -> c
instance Mult Int Int Int where
times x y = x * y
instance Ix a => Mult Int (Array a Int) (Array a Int) where
times x y = fmap (*x) y
----------------------------------------------------------
-- Generic Monad operations from prelude
{-
sequence :: Monad m => [m a] -> m [a]
sequence = foldr mcons (return [])
where mcons p q = do x <- p
xs <- q
return (x:xs)
sequence_ :: Monad m => [m a] -> m ()
sequence_ = foldr (>>) (return ())
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM f as = sequence (map f as)
mapM_ :: Monad m => (a -> m b) -> [a] -> m ()
mapM_ f as = sequence_ (map f as)
(=<<) :: Monad m => (a -> m b) -> m a -> m b
f =<< x = x >>= f
-}
{- Other topics
functional dependencies
implicit parameters
-}
-----------------------------------------------------------
-- The meaning of Overloaded functions
class Equal a where
equal :: a -> a -> Bool
class Nat a where
inc :: a -> a
dec :: a -> a
zero :: a -> Bool
f0 :: (Equal a, Nat a) => a -> a
f0 x =
if zero x && equal x x
then inc x
else dec x
instance Equal Int where
equal x y = x==y
instance Nat Int where
inc x = x+1
dec x = x+1
zero 0 = True
zero n = False
data N = Z | S N
instance Equal N where
equal Z Z = True
equal (S x) (S y) = equal x y
equal _ _ = False
instance Nat N where
inc x = S x
dec (S x) = x
zero Z = True
zero (S _) = False
instance Equal a => Equal [a] where
equal [] [] = True
equal (x:xs) (y:ys) = equal x y && equal xs ys
equal _ _ = False
instance Nat a => Nat [a] where
inc xs = map inc xs
dec xs = map dec xs
zero xs = all zero xs
---------------------------------------
data EqualL a = EqualL
{ equalM :: a -> a -> Bool
}
data NatL a = NatL
{ incM :: a -> a
, decM :: a -> a
, zeroM :: a -> Bool
}
f1 :: EqualL a -> NatL a -> a -> a
f1 el nl x =
if zeroM nl x && equalM el x x
then incM nl x
else decM nl x
-- instances using the library passing transform
instance_l1 :: EqualL Int
instance_l1 = EqualL {equalM = equal } where
equal x y = x==y
instance_l2 :: NatL Int
instance_l2 = NatL { incM=inc, decM=dec, zeroM=zero } where
inc x = x+1
dec x = x+1
zero 0 = True
zero n = False
instance_l3 :: EqualL N
instance_l3 = EqualL { equalM = equal } where
equal Z Z = True
equal (S x) (S y) = equal x y
equal _ _ = False
instance_l4 :: NatL N
instance_l4 = NatL {incM = inc, decM = dec, zeroM = zero } where
inc x = S x
dec (S x) = x
zero Z = True
zero (S _) = False
instance_l5 :: EqualL a -> EqualL [a]
instance_l5 lib = EqualL { equalM = equal } where
equal [] [] = True
equal (x:xs) (y:ys) = equalM lib x y && equal xs ys
equal _ _ = False
instance_l6 :: NatL a -> NatL [a]
instance_l6 lib = NatL { incM = inc, decM =dec, zeroM = zero } where
inc xs = map (incM lib) xs
dec xs = map (decM lib) xs
zero xs = all (zeroM lib) xs
---------------------------------
data Proof a b = Ep{from :: a->b, to:: b->a}
data Rep t
= Int (Proof t Int)
| Char (Proof t Char)
| Unit (Proof t ())
| forall a b . Arr (Rep a) (Rep b) (Proof t (a->b))
| forall a b . Prod (Rep a) (Rep b) (Proof t (a,b))
| forall a b . Sum (Rep a) (Rep b) (Proof t (Either a b))
| N (Proof t N)
| forall a . List (Rep a) (Proof t [a])
equalX :: Rep a -> a -> a -> Bool
incX :: Rep a -> a -> a
decX :: Rep a -> a -> a
zeroX :: Rep a -> a -> Bool
f2 :: Rep a -> a -> a
f2 r x =
if zeroX r x && equalX r x x
then incX r x
else decX r x
incX (Int p) x = to p (inc (from p x)) where inc x = x+1
incX (N p) x = to p (inc (from p x)) where inc x = S x
incX (List a p) x = to p (inc (from p x)) where inc xs = map (incX a) xs
decX (Int p) x = to p (dec (from p x)) where dec x = x+1
decX (N p) x = to p (dec (from p x)) where dec x = S x
decX (List a p) x = to p (dec (from p x)) where dec xs = map (decX a) xs
zeroX (Int p) x = zero (from p x) where zero 0 = True
zero n = False
zeroX (N p) x = zero (from p x) where zero Z = True
zero (S _) = False
zeroX (List a p) x = zero (from p x) where zero xs = all (zeroX a) xs
equalX (Int p) x y = h equal p x y where equal x y = x==y
equalX (N p) x y = h equal p x y where equal Z Z = True
equal (S x) (S y) = equal x y
equal _ _ = False
equalX (List a p) x y = h equal p x y where equal [] [] = True
equal (x:xs) (y:ys) = equalX a x y && equal xs ys
equal _ _ = False
h equal p x y = equal (from p x) (from p y)
--