在Haskell中实现Iota

时间:2012-08-14 21:12:37

标签: haskell scheme implementation iota

Iota是一种只使用一个组合器的小型“编程语言”。我很想了解它是如何工作的,但是用我熟悉的语言看实现会很有帮助。

我找到了用Scheme编写的Iota编程语言的实现。我在将它翻译成Haskell时遇到了一些麻烦。它相当简单,但我对Haskell和Scheme都相对较新。

您如何在Haskell中编写等效的Iota实现?

(let iota ()
  (if (eq? #\* (read-char)) ((iota)(iota))
      (lambda (c) ((c (lambda (x) (lambda (y) (lambda (z) ((x z)(y z))))))
           (lambda (x) (lambda (y) x))))))

1 个答案:

答案 0 :(得分:13)

我一直在教自己一些这样的东西,所以我当然希望我能得到以下的正确...

早上好提到,输入Haskell的事实对这个问题非常重要;类型系统限制可以形成的表达式,特别是lambda演算的最基本类型系统禁止自我应用,最终为您提供非图灵完整语言。图灵齐全性在基本类型系统的顶层上添加作为语言的额外功能(fix :: (a -> a) -> a运算符或递归类型)。

这并不意味着你无法在Haskell中实现这一点,而是这样的实现不会只有一个运算符。

方法#1:实施second example one-point combinatory logic basis from here,并添加fix功能:

iota' :: ((t1 -> t2 -> t1)
          -> ((t5 -> t4 -> t3) -> (t5 -> t4) -> t5 -> t3)
          -> (t6 -> t7 -> t6)
          -> t)
         -> t
iota' x = x k s k 
    where k x y = x
          s x y z = x z (y z)

fix :: (a -> a) -> a
fix f = let result = f result in result

现在,您可以根据iota'fix编写任何程序。解释这是如何工作的有点涉及。 (编辑:请注意,此iota'与原始问题中的λx.x S K不同;它是λx.x K S K,也是图灵完备。它是iota'程序将与iota程序不同的情况。我在Haskell中尝试了iota = λx.x S K定义;它是类型检查,但是当你尝试k = iota (iota (iota iota))和{时{1}}您收到类型错误。)

方法#2:使用此递归类型可以将无类型的lambda演算表示嵌入到Haskell中:

s = iota (iota (iota (iota iota)))

newtype D = In { out :: D -> D } 基本上是一种类型,其元素是从DD的函数。我们DIn :: (D -> D) -> D函数转换为普通D -> D,并D执行相反的操作。因此,如果我们有out :: D -> (D -> D),我们可以通过x :: D自我应用。

说明,现在我们可以写:

out x x :: D

这需要来自iota :: D iota = In $ \x -> out (out x s) k where k = In $ \x -> In $ \y -> x s = In $ \x -> In $ \y -> In $ \z -> out (out x z) (out y z) In的一些“噪音”; Haskell仍禁止您将out应用于D,但我们可以使用DIn来解决此问题。实际上,您无法对类型为out的值执行任何有用的操作,但您可以围绕相同的模式设计有用的类型。


编辑: iota基本上是D,其中λx.x S KK = λx.λy.x。即,iota采用双参数函数并将其应用于S和K;所以通过传递返回其第一个参数的函数得到S,并通过传递返回其第二个参数的函数得到K.所以如果你可以用iota写“返回第一个参数”和“返回第二个参数”,你可以用iota写S和K.但是S and K are enough to get Turing completeness,所以你也可以在讨价还价中获得图灵的完整性。事实证明你可以使用iota编写必要的选择器函数,因此iota足以满足图灵的完整性。

因此,这减少了理解iota以理解SK微积分的问题。