haskell - Church naturals、求幂函数和类型检查

标签 haskell lambda numbers church-encoding

我对 lambda 演算中的自然数有如下定义,这是我的主要目标。

-- Apply a function n times on x
apply = \f -> \n -> \x -> foldr ($) x $ replicate n f

-- Church numbers
churchZero = \f -> id

churchOne = \f -> \x -> apply f 1 x

churchTwo = \f -> \x -> apply f 2 x

churchNatural = \n -> \f -> \x -> apply f n x

然后,下一步是定义运算符 churchSumchurchMulchurchExp

churchSum = \n -> \m -> \f -> \x -> n f (m f x)

churchMul = \n -> \m -> \f -> \x -> n (m f) x

churchExp = \n -> \m -> n m

很好,它有效,前两个函数“很容易”推导出来,但取幂却不是。至少对我来说。为了了解更多,我对 lambda 项进行了 beta 归一化:
(λf.λx.f(f x))(λf.λx f(f x)) 看看实际上,求幂是正确的。

beta reduction

所以,我的问题是:我如何在不知道它的情况下推导出这个求幂的 lambda 项?甚至,当类型为 λ> churchTwo::(b -> b) -> b -> b?在里面做函数的 beta 归一化?

最佳答案

你的 exp有点倒退:

((\f x -> f$f$f$x) `exp` (\f x -> f$f$x)) (+1) 0 == 8
--      3            ^          2                 = 8???
-- But 2^3 = 8

正确的(-er-ish)版本是

exp n m = m n
((\f x -> f$f$f$x) `exp` (\f x -> f$f$x)) (+1) 0 == 9
--      3            ^          2                 = 9

因为它保持着熟悉的秩序。这并不真正影响您如何定义 exp。 .


指数是重复乘法:n<sup>m</sup>n自相乘m次。教堂数字表示函数对值的重复应用。所以,churchMul n是一个将数字乘以 n 的函数, m是重复函数 m 的函数次,和churchOne是基值(乘法恒等式)。将它们放在一起,然后简化:

-- n^m is the repeated multiplication of 1 by n, m times
exp n m = m (churchMul n) churchOne
-- expand definitions x2; simplify churchOne
exp n m = m (\o f x -> n (o f) x) (\f x -> f x)
-- eta contract x2
exp n m = m (\o f -> n (o f)) (\f -> f)
-- definition of (.), id
exp n m = m (\o -> n . o) id
-- eta contract
exp n m = m (n .) id
-- eta expand
exp n m f = m (n .) id f
-- Assume m has the type forall b. (b -> b) -> b -> b
-- This assumption may actually be false here, because the implicit type of exp
-- does not require that m, n have that type. The difference is that you could define
-- bogus _ _ _ = 0
-- (which isn't a church numeral) and still pass it to exp, which would no longer
-- act like exponentiation:
-- exp n bogus = bogus (n .) id = const 0
-- which also isn't a church numeral

-- Polymorphic functions like m give rise to theorems that can be derived
-- entirely from their types. I used http://www-ps.iai.uni-bonn.de/cgi-bin/free-theorems-webui.cgi
-- to get this one automatically.
-- Free theorem of the type of m
forall a b (g :: a -> b) (p :: a -> a) (q :: b -> b).
   (forall (x :: a). g (p x) = q (g x)) ->
     (forall (y :: a). g (m p y) = m q (g y))

-- Instantiate g = ($ f), p = (n .), q = n, y = id
  (forall x. (n . x) f = n (x f)) -> (m (n .) id f = m n f)

-- definition of (.)
  (n . x) f = n (x f)
-- so...
  m (n .) id f = m n f
-- transitive property
exp n m f = m n f
-- eta contract
exp n m = m n

上面的东西与m的自由定理实际上是以下论证的严格版本(这可能更好地转化为无类型的 lambda 演算):

-- m, being a valid numeral, is of the form
m f x = f $ f $ ... $ f $ f $ x

m (n .) id = (n .) $ (n .) $ ... $ (n .) $ (n .) $ id
           = (n .) $ (n .) $ ... $ (n .) $ n . id
           = (n .) $ (n .) $ ... $ (n .) $ n
           = (n .) $ (n .) $ ... $ n . n
           ...
           = n . n . ... . n . n
-- so
m n = n . n . ... . n . n = m (n .) id

至于为什么churchTwo churchTwo类型检查,请注意该表达式中的每个事件都有不同的类型,因为 churchTwo是多态的,描述了一整套函数,而不仅仅是一个函数。

-- most general type
churchTwo :: forall b. (b -> b) -> (b -> b)
-- Each occurrence of churchTwo can have a different type, so let's give them
-- different names.
-- I'm using underscores because these variables haven't been solved yet
churchTwo0 :: (_b0 -> _b0) -> (_b0 -> _b0)
churchTwo1 :: (_b1 -> _b1) -> (_b1 -> _b1)
churchTwo0 churchTwo1 :: _
-- Since churchTwo0 is being applied, the whole expression must have the
-- type on the right of the arrow
churchTwo0 churchTwo1 :: _b0 -> _b0
-- Since churchTwo0 is being applied to churchTwo1, the left side of the
-- top level arrow in churchTwo0 must be equal to the type of churchTwo1
(_b0 -> _b0) ~ ((_b1 -> _b1) -> (_b1 -> _b1))
-- Therefore...
(_b0 ~ (_b1 -> _b1))
churchTwo0 churchTwo1 :: (_b1 -> _b1) -> (_b1 -> _b1)
-- That's all the constraints we have, so replace the free variables
-- with universally quantified ones
chuchTwo0 churchTwo1 :: forall b. (b -> b) -> (b -> b)
-- (which is the type of a numeral)

关于haskell - Church naturals、求幂函数和类型检查,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47563925/

相关文章:

arrays - 对于具有数百万像素的 2D、未装箱像素阵列,建议使用什么 Haskell 表示法?

sockets - Lambda + API网关: Long executing function return before task finished

javascript - JQuery/JavaScript 增量数

c - 数组的 For 循环 - 从以前的值添加

python - 为 Python 安装 Bigfloat

haskell - Haskell 中通过 unsafePerformIO 的全局变量

haskell - 为什么这个词法分析器不解析这个输入?

haskell - 我是否必须仅仅因为我想提取一些功能而将隐藏包移动到 Haskell 项目中的项目依赖项?

python - 使用 waiter.wait 时 AWS Lambda 作业运行两次

c# - 从 C# 到 VB.Net 的 Lambda 表达式