请注意以下Haskell计划:
-- Lambda Calculus ADT
data Term = Fun (Term -> Term) | Num !Double
instance Show Term where
show (Num x) = "(Num "++(if fromIntegral (floor x) == x then show (floor x) else show x)++")"
show (Fun _) = "(<function>)"
-- Lambda Calculus term application
(#) :: Term -> Term -> Term
(Fun f) # x = f x
infixl 0 #
-- We have floats as primitives for performance
float_toChurch :: Term
float_toChurch = Fun (\ (Num n) -> Fun (\f -> Fun (\x ->
if n <= 0
then x
else (f # (float_toChurch # (Num (n - 1)) # f # x)))))
float_add :: Term
float_add = Fun (\ (Num x) -> Fun (\ (Num y) -> Num (x + y)))
-- Function compiled from the Lambda Calculus.
-- It sums all nats from 0 til a number.
sum_til :: Term
sum_til = (Fun(\v0->((((((float_toChurch # v0) # (Fun(\v1->(Fun(\v2->(Fun(\v3->(Fun(\v4->((v3 # v2) # (((v1 # ((float_add # v2) # (Num 1))) # v3) # v4))))))))))) # (Fun(\v1->(Fun(\v2->(Fun(\v3->v3))))))) # (Num 0)) # (Fun(\v1->(Fun(\v2->((float_add # v2) # v1)))))) # (Num 0))))
-- Testing it
main = do
let n = 512*512*8
print $ (sum_til # (Num n))
由于周围没有快速的lambda计算器,我使用上面的策略将Untyped Lambda Calculus的术语编译为Haskell,以便快速评估它们。我对性能印象深刻:该程序会创建一个从0
到2097152
的数字列表,并在不到一秒钟的时间内将它们汇总到我的计算机上。这比我预期的要快得多 - 只比Haskell direct equivalent慢4倍 - 足以对我的目标有用。然而,请注意我必须在Fun / Num构造函数下包装函数和术语以满足类型系统。拳击可能不太理想。所以,我的问题是:是否可以运行相同的Lambda微积分程序并获得更快的相同结果?即,任何方法来删除拳击? (此外,它不需要 来使用Haskell。)