zot-0.0.2: src/SKI.hs
module SKI where
data Rec a
= In { out :: Rec a -> Rec a }
| Int { fromInt :: Int }
| Char Char | Bool Bool
| Error String
instance Eq ( Rec a ) where
Int i == Int j = i == j
Char c == Char d = c == d
Bool b == Bool c = b == c
In _ == In _ = error "can not compare"
_ == _ = False
instance Show ( Rec a ) where
show ( Int i ) = show i
show ( Error e ) = "Error: " ++ e
show _ = "function"
suc :: Rec a
suc = In scc
where
scc ( Int i ) = Int $ succ i
scc ( Char c ) = Char $ succ c
scc _ = error "not int"
out_ :: Rec a -> Rec a -> Rec a
out_ x = case x of
In f -> f
_ -> \_ -> Error "not function"
oi :: Rec a -> Rec a
oi x = x
ii :: Rec a
ii = In oi
ok :: Rec a -> Rec a
ok x = In $ \_ -> x
k :: Rec a
k = In ok
os :: Rec a -> Rec a
-- s x y z = x z ( y z )
os x = In $ \y -> In $ \z -> ( out_ $ out_ x z ) ( out_ y z )
s :: Rec a
s = In os
readChurch :: Rec a -> Rec a
readChurch cn = cn `out_` suc `out_` Int 0
mkski :: String -> Rec a
mkski = fst . makeSKI
makeSKI :: String -> ( Rec a, String )
makeSKI ( '`' : rest ) = let
( c, rest' ) = makeSKI rest
( c', rest'' ) = makeSKI rest' in case c of
In f -> ( f c', rest'' )
_ -> ( Error "in makeSKI", rest'' )
-- ( out c c', rest'' )
makeSKI ( 's' : rest ) = ( s, rest )
makeSKI ( 'k' : rest ) = ( k, rest )
makeSKI ( 'i' : rest ) = ( ii, rest )
makeSKI _ = error "makeSKI error"
sc :: Rec a
sc = mkski "`s``s`ks``s`kki"
mul :: Rec a -> Rec a -> Rec a
mul x y = out ( out x ( out y sc ) ) ( out k ii )