我已经安装了CEK机器。给定这种算法的闭包结果,并且知道这种闭包是教会编码的数字,那么打印数字的最佳方法是什么?
使用以下类型:
data Term = Var String | Abs String Term | App Term Term
data Clos = Clos String Term Env
type Env = [(String, Clos)]
编辑:
为了使这个模糊的问题更加清楚:
我以(\n f x -> f (n f x)) (\f x -> x)
(s z
)来启动机器,结果是:
(\f -> (\x -> (f ((n f) x)))) :: Term
[("n", Clos((\f -> (\x -> x)), []))] :: Env
这是一个数据结构,它表示一个代表教堂数字的闭包。如何将这个结构化为数字?我是否必须遍历闭包的环境并在Term
中替换变量(声音效率低下)?我需要为此重命名吗?
编辑: 实际代码:
data Term = Var String | Abs String Term | App Term Term deriving (Show)
data Clos = Clos String Term Env deriving (Show)
type Env = [(String, Clos)]
data Frame = FArg Term Env | FFun Clos deriving (Show)
data State = State Term Env [Frame] deriving (Show)
step :: State -> Maybe State
step (State (Var x) env k) = fmap (\(Clos y b env') -> State (Abs y b) env' k) $ lookup x env
step (State (App a b) env k) = return $ State a env (FArg b env : k)
step (State (Abs x b) env (FArg t env' : k)) = return $ State t env' (FFun (Clos x b env) : k)
step (State (Abs x b) env (FFun (Clos y b' env') : k)) = return $ State b' ((y, Clos x b env) : env') k
step _ = Nothing
steps :: State -> State
steps st = maybe st steps (step st)
z = Abs "f" $ Abs "x" $ Var "x"
s = Abs "n" $ Abs "f" $ Abs "x" $ App (Var "f") $ App (App (Var "n") (Var "f")) (Var "x")
term = App s z
result = steps $ State term [] []
main = putStrLn $ show result
结果:
State (Abs "f" (Abs "x" (App (Var "f") (App (App (Var "n") (Var "f")) (Var "x"))))) [("n",Clos "f" (Abs "x" (Var "x")) [])] []
答案 0 :(得分:3)
教堂数字是两个自变量的函数
type Church a = (a -> a) -> a -> a
第二个参数为零大小写,第一个参数为增量大小写。因此,您只需要将数字应用于适当的几个参数即可获得某些(通常为数字)数据类型:
fromChurch c = c (+ 1) (0 :: Int)