Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Haskell中实现物联网_Haskell_Scheme_Implementation_Iota - Fatal编程技术网

在Haskell中实现物联网

在Haskell中实现物联网,haskell,scheme,implementation,iota,Haskell,Scheme,Implementation,Iota,Iota是一种非常小的“编程语言”,只使用一个组合器。我很想了解它是如何工作的,但是如果能用一种我熟悉的语言看到它的实现,那会很有帮助 我发现了一个用Scheme编写的Iota编程语言的实现。不过我在把它翻译成Haskell时遇到了点麻烦。这相当简单,但我对Haskell和Scheme都比较陌生 您将如何在Haskell中编写等效的Iota实现 (let iota () (if (eq? #\* (read-char)) ((iota)(iota)) (lambda (c) ((

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))))))

我一直在自学这些东西,所以我真的希望我能做到以下几点

正如n.m.提到的,Haskell是打字的,这一事实对这个问题非常重要;类型系统限制可以形成什么表达式,特别是lambda演算的最基本类型系统禁止自应用,这最终会给您一种非图灵完整语言。图灵完整性作为语言的一个额外功能添加到基本类型系统之上(a
fix::(a->a)->a
运算符或递归类型)

这并不意味着你不能在Haskell中实现这一点,而是说这样的实现不会只有一个操作符

方法#1:实现,并添加一个
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
程序。我尝试了
iota=λx.x S K
定义Haskell中的初始化;它会进行类型检查,但当您尝试
k=iota(iota(iota-iota))
s=iota(iota(iota-iota)))
时,会出现类型错误。)

方法#2:可以使用以下递归类型将非类型lambda演算表示嵌入Haskell中:

newtype D = In { out :: D -> D }
D
基本上是一种类型,其元素是从
D
D
的函数。我们有
In::(D->D)->D
D->D
函数转换为普通的
D
,而
out::D->(D->D)
则做相反的事情。因此,如果我们有
x::D
,我们可以通过执行
out 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
out
发出一些“噪音”;Haskell仍然禁止您将
D
应用于
D
,但我们可以使用
In
out
来解决此问题。实际上,您不能对
D
类型的值做任何有用的事情,但可以围绕相同的模式设计一个有用的类型


编辑:物联网基本上是
λx.x S K
,其中
K=λx.λy.x
S=λx.λy.λz.x z(y z)
。即,iota采用双参数函数,并将其应用于S和K;因此,通过传递一个返回其第一个参数的函数,可以得到S,通过传递一个返回其第二个参数的函数,可以得到K。因此,如果可以使用iota编写“返回第一个参数”和“返回第二个参数”,则可以使用iota编写S和K。但是,你也可以在交易中得到图灵完全性。事实证明,您可以使用iota编写必要的选择器函数,因此iota足以满足图灵完整性的要求


因此,这将理解iota的问题简化为理解SK演算。

Haskell中没有等效的实现。这样的实现不会进行类型检查。当然,可以使用不同的策略编写实现。是的,我知道它不会进行类型检查。我想我被绊倒的部分是理解((iota)(iota))在这个实现中所做的事情。我无法理解方法2,但我开始掌握方法1。您愿意更详细地解释一下吗?fix操作符到底是如何工作的?
fix
是一个函数,它基本上将无界递归引入到缺少它的语言中。如果您听说过Y组合器,
fix
在Haskell中是等效的。简短的解释是,
fixf=f(f(f(f…))
(一个无限的
f
)应用程序塔);由于在Haskell中,
f
可能是懒惰的,
f
可以选择返回一个值,而不使用
f
(基本情况)或使用
f(f(f(f…))
堆栈(递归情况)。关于
修复
:通常可以转换递归函数
f=λx。。。f y…
添加一个表示递归情况的额外参数,并对结果进行修正:
f=fix(λrec x……rec y…
。在第一种方法中,您编写了
iota x=x k s k
,在第二种方法中-“iota基本上是
λx.x s k
”。那可能是打字错误吗?@威利斯:不,不是打字错误。显示了两种可能的定义方式,这导致了基于物联网的
s
k
的不同定义。但是,出于某种原因,如果在Haskell中使用
λx.x S K
版本,而该版本进行了类型检查,则相关的
S
K
定义不起作用。