【发布时间】:2020-06-04 18:12:13
【问题描述】:
请注意以下 Haskell 程序:
-- A HOAS term, non-polymorphic for simplicity
data Term
= Lam (Term -> Term)
| App Term Term
| Num Int
-- Doubles every constant in a term
fun0 :: Term -> Term
fun0 (Lam b) = Lam (\ x -> fun0 (b x))
fun0 (App f x) = App (fun0 f) (fun0 x)
fun0 (Num i) = Num (i * 2)
-- Same function, using a continuation-passing style
fun1 :: Term -> (Term -> a) -> a
fun1 (Lam b) cont = undefined
fun1 (App f x) cont = fun1 f (\ f' -> fun1 x (\ x' -> cont (App f' x')))
fun1 (Num i) cont = cont (Num (i * 2))
-- Sums all nums inside a term
summ :: Term -> Int
summ (Lam b) = summ (b (Num 0))
summ (App f x) = summ f + summ x
summ (Num i) = i
-- Example
main :: IO ()
main = do
let term = Lam $ \ x -> Lam $ \ y -> App (App x (Num 1)) (App y (Num 2))
print (summ term) -- prints 3
print (summ (fun0 term)) -- prints 6
print (fun1 term $ \ t -> summ t) -- a.hs: Prelude.undefined
这里,Term 是一个带有数字常量的(非多态)λ 项,fun0 是一个将项内的所有常量加倍的函数。是否可以以延续传递风格重写fun0?换句话说,是否有可能完成fun1 函数的undefined 情况,使其行为与fun0 相同,并且最后一个print 输出6?
【问题讨论】:
标签: haskell continuation-passing