Greg Buchholz wrote:
Keean Schupke wrote:
Haskell is not dependantly typed, so cannot deal with types that "depend" on
values.
Can anyone recommend a nice dependently typed language to play with?
Cayenne, Epigram, other?
I have refactored your code into a type level Haskell program.
This has the nice advantage that it is extensible. You can add a new
primitive to the language as:
data PrimName
primName :: PrimName
primName = undefined
instance Apply PrimName a b where
apply _ a = {- method implementing primName -}
Programs are assembled as types like:
fac4 = lit nul `o` lit suc `o` lit (dup `o` pre)
`o` lit mult `o` linrec
Recursion requires a primitive to aviod infinite types, see
definitions of times, linrec and genrec.
programs are run by applying the contructed type representing the
program to a stack... for example:
putStrLn $ show $ apply (lit hThree `o` fac4) hNil
We could have written this:
putStrLn $ show $ apply fac4 (hCons hThree hNil)
I have attached the debugged code, simply load into ghci, in the same
directory as the HList library (download http://www.cwi.nl/~ralf/HList)
as Joy.hs.
ghci -fallow-overlapping-instances Joy.hs
(you need the flag to get the code to run interactively, however you
dont need the flag just to run 'main' to perform the factorial tests)
Keean.
{-# OPTIONS -fglasgow-exts #-}
{-# OPTIONS -fallow-overlapping-instances #-}
{-# OPTIONS -fallow-undecidable-instances #-}
module Joy where
import MainGhcGeneric1
type HOne = HSucc HZero
hOne :: HOne
hOne = undefined
type HTwo = HSucc HOne
hTwo :: HTwo
hTwo = undefined
type HThree = HSucc HTwo
hThree :: HThree
hThree = undefined
data Lit a
lit :: a -> Lit a
lit = undefined
unl :: Lit a -> a
unl = undefined
instance HList s => Apply (Lit a) s (HCons a s) where
apply a s = hCons (unl a) s
class (HBool b,HList s) => HIfte b t f s s' | b t f s -> s' where
hIfte :: b -> t -> f -> s -> s'
instance (HList s,Apply t s s') => HIfte HTrue t f s s' where
hIfte _ t _ s = apply t s
instance (HList s,Apply f s s') => HIfte HFalse t f s s' where
hIfte _ _ f s = apply f s
data Ifte
ifte :: Ifte
ifte = undefined
instance (Apply b s r,HHead r b',HIfte b' t f s s')
=> Apply Ifte (HCons f (HCons t (HCons b s))) s' where
apply _ (HCons f (HCons t (HCons b s))) = hIfte (hHead (apply b s :: r) :: b') t f s
data Nul
nul :: Nul
nul = undefined
instance HList s => Apply Nul (HCons HZero s) (HCons HTrue s) where
apply _ (HCons _ s) = hCons hTrue s
instance HList s => Apply Nul (HCons (HSucc n) s) (HCons HFalse s) where
apply _ (HCons _ s) = hCons hFalse s
data EQ
eq :: EQ
eq = undefined
instance (HList s,TypeEq a b t) => Apply EQ (HCons a (HCons b s)) (HCons t s) where
apply _ (HCons a (HCons b s)) = hCons (typeEq a b) s
data Dip
dip :: Dip
dip = undefined
instance (HList s,HList s',Apply a s s') => Apply Dip (HCons a (HCons b s)) (HCons b s') where
apply _ (HCons a (HCons b s)) = hCons b (apply a s)
data Dup
dup :: Dup
dup = undefined
instance HList s => Apply Dup (HCons a s) (HCons a (HCons a s)) where
apply _ s@(HCons a _) = hCons a s
data Pop
pop :: Pop
pop = undefined
instance HList s => Apply Pop (HCons a s) s where
apply _ (HCons _ s) = s
data Swap
swap :: Swap
swap = undefined
instance HList s => Apply Swap (HCons a (HCons b s)) (HCons b (HCons a s)) where
apply _ (HCons a (HCons b s)) = hCons b (hCons a s)
data Suc
suc :: Suc
suc = undefined
instance (HNat a,HList s) => Apply Suc (HCons a s) (HCons (HSucc a) s) where
apply _ (HCons _ s) = hCons (undefined::HSucc a) s
data Pre
pre :: Pre
pre = undefined
instance (HNat a,HList s) => Apply Pre (HCons (HSucc a) s) (HCons a s) where
apply _ (HCons _ s) = hCons (undefined::a) s
data Add
add :: Add
add = undefined
instance (HList s,HAdd a b c) => Apply Add (HCons a (HCons b s)) (HCons c s) where
apply _ (HCons _ (HCons _ s)) = hCons (hAdd (undefined::a) (undefined::b)) s
class (HNat a,HNat b) => HAdd a b c | a b -> c where
hAdd :: a -> b -> c
instance HAdd HZero HZero HZero where
hAdd _ _ = hZero
instance HNat b => HAdd HZero (HSucc b) (HSucc b) where
hAdd _ b = b
instance HNat a => HAdd (HSucc a) HZero (HSucc a) where
hAdd a _ = a
instance (HNat (HSucc a),HNat (HSucc b),HNat c,HAdd a b c)
=> HAdd (HSucc a) (HSucc b) (HSucc (HSucc c)) where
hAdd _ _ = hSucc $ hSucc $ hAdd (undefined::a) (undefined::b)
data Sub
sub :: Sub
sub = undefined
instance (HList s,HSub a b c) => Apply Sub (HCons b (HCons a s)) (HCons c s) where
apply _ (HCons _ (HCons _ s)) = hCons (hSub (undefined::a) (undefined::b)) s
class (HNat a,HNat b) => HSub a b c | a b -> c where
hSub :: a -> b -> c
instance HSub HZero HZero HZero where
hSub _ _ = hZero
instance HNat a => HSub (HSucc a) HZero (HSucc a) where
hSub a _ = a
instance HNat a => HSub HZero (HSucc a) HZero where
hSub _ _ = hZero
instance (HSub a b c) => HSub (HSucc a) (HSucc b) c where
hSub _ _ = hSub (undefined::a) (undefined::b)
data Mult
mult :: Mult
mult = undefined
instance (HList s,HMult a b c) => Apply Mult (HCons a (HCons b s)) (HCons c s) where
apply _ (HCons _ (HCons _ s)) = hCons (hMult (undefined::a) (undefined::b)) s
class (HNat a,HNat b) => HMult a b c | a b -> c where
hMult :: a -> b -> c
instance HNat b => HMult HZero b HZero where
hMult _ _ = hZero
instance (HMult a b s,HAdd b s s') => HMult (HSucc a) b s' where
hMult _ _ = hAdd (undefined::b) (hMult (undefined::a) (undefined::b) :: s)
data Seq a b
o :: a -> b -> (Seq a b)
o _ _ = undefined
leftOp :: (Seq a b) -> a
leftOp _ = undefined
rightOp :: (Seq a b) -> b
rightOp _ = undefined
instance (HList s,Apply a s s',Apply b s' s'') => Apply (Seq a b) s s'' where
apply op s = apply (rightOp op) (apply (leftOp op) s :: s')
square = dup `o` mult
cube = dup `o` dup `o` mult `o` mult
data I
i :: I
i = undefined
instance (HList s,Apply a s s') => Apply I (HCons a s) s' where
apply _ (HCons a s) = apply a s
data Times
times :: Times
times = undefined
instance HList s => Apply Times (HCons p (HCons HZero s)) s where
apply _ (HCons _ (HCons _ s)) = s
instance (HNat n,HList s,HList s',Apply p s s',Apply Times (HCons p (HCons n s')) s'')
=> Apply Times (HCons p (HCons (HSucc n) s)) s'' where
apply _ (HCons p (HCons _ s)) = apply times (hCons p (hCons (undefined::n) (apply p s)))
class (HBool f,HList s) => HGenrec f r1 r2 b t s s'' | f r1 r2 b t s -> s'' where
hGenrec :: f -> r1 -> r2 -> b -> t -> s -> s''
instance (HList s,Apply t s s') => HGenrec HTrue r1 r2 b t s s' where
hGenrec _ _ _ _ t s = apply t s
instance (HList s,HList s',Apply r1 s s',
Apply r2 (HCons (Seq (Seq (Seq (Seq (Lit b) (Lit t)) (Lit r1)) (Lit r2)) Genrec) s') s'')
=> HGenrec HFalse r1 r2 b t s s'' where
hGenrec _ r1 r2 b t s = apply (lit (lit b `o` lit t `o` lit r1 `o` lit r2 `o` genrec) `o` r2) (apply r1 s)
data Genrec
genrec :: Genrec
genrec = undefined
instance (Apply b s s',HHead s' b',HGenrec b' r1 r2 b t s s'')
=> Apply Genrec (HCons r2 (HCons r1 (HCons t (HCons b s)))) s'' where
apply _ (HCons r2 (HCons r1 (HCons t (HCons b s))))
= hGenrec (hHead (apply b s :: s') :: b') r1 r2 b t s
class (HBool f,HList s) => HLinrec f b t r1 r2 s s' | f b t r1 r2 s -> s' where
hLinrec :: f -> b -> t -> r1 -> r2 -> s -> s'
instance (HList s,Apply t s s') => HLinrec HTrue b t r1 r2 s s' where
hLinrec _ _ t _ _ s = apply t s
instance (HList s,HList s',Apply r1 s s',
Apply Linrec (HCons r2 (HCons r1 (HCons t (HCons b s')))) s'',Apply r2 s'' s''')
=> HLinrec HFalse b t r1 r2 s s''' where
hLinrec _ b t r1 r2 s = apply r2 (apply linrec (hCons r2 (hCons r1 (hCons t (hCons b (apply r1 s :: s'))))) :: s'')
data Linrec
linrec :: Linrec
linrec = undefined
instance (Apply b s s',HHead s' b',HLinrec b' b t r1 r2 s s'') => Apply Linrec (HCons r2 (HCons r1 (HCons t (HCons b s)))) s'' where
apply _ (HCons r2 (HCons r1 (HCons t (HCons b s)))) = hLinrec (hHead (apply b s :: s') :: b') b t r1 r2 s
data Fact1
fact1 :: Fact1
fact1 = undefined
instance (HList s,Apply (Seq (Seq (Seq (Lit (Seq (Lit HZero) EQ))
(Lit (Seq Pop (Lit (HSucc HZero)))))
(Lit (Seq (Seq (Seq (Seq Dup (Lit (HSucc HZero))) Sub) Fact1) Mult)))
Ifte) s s') => Apply Fact1 s s' where
apply _ s = apply fac1 s
fac1 = lit (lit hZero `o` eq)
`o` lit (pop `o` lit hOne)
`o` lit (dup `o` lit hOne `o` sub `o` fact1 `o` mult)
`o` ifte
fac2 = lit (lit hOne `o` lit hOne)
`o` dip `o` lit (dup `o` lit mult `o` dip `o` suc)
`o` times `o` pop
fac3 = lit nul `o` lit suc `o` lit (dup `o` pre)
`o` lit (i `o` mult) `o` genrec
fac4 = lit nul `o` lit suc `o` lit (dup `o` pre)
`o` lit mult `o` linrec
main :: IO ()
main = do
putStrLn $ show $ apply (lit hThree `o` fac1) hNil
putStrLn $ show $ apply (lit hThree `o` fac2) hNil
putStrLn $ show $ apply (lit hThree `o` fac3) hNil
putStrLn $ show $ apply (lit hThree `o` fac4) hNil
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe