Haskell 元组声明进入无限循环

Haskell 元组声明进入无限循环,haskell,tuples,infinite-loop,Haskell,Tuples,Infinite Loop,在序曲中尝试这一点 Prelude> (i, j) = (3, 4) Prelude> (i, j) = (j, i) Prelude> i 我本来期望4,但我得到了一个无限循环 为什么? 如何以简洁优雅的方式做到这一点?我能想到的最短顺序是: (i', j') = (i, j) (i, j) = (j', i') 这当然只对GHCi有效,就像原始序列一样。在普通Haskell模块中,此类定义不能出现在同一词汇范围内。如果您定义 ghci> factorial n =

在序曲中尝试这一点

Prelude> (i, j) = (3, 4)
Prelude> (i, j) = (j, i)
Prelude> i
我本来期望
4
,但我得到了一个无限循环

为什么?


如何以简洁优雅的方式做到这一点?

我能想到的最短顺序是:

(i', j') = (i, j)
(i, j) = (j', i')
这当然只对GHCi有效,就像原始序列一样。在普通Haskell模块中,此类定义不能出现在同一词汇范围内。

如果您定义

ghci> factorial n = if n == 0 then 1 else n * (factorial (n - 1))
您希望在RHS上使用的
factorial
与在LHS上使用的
factorial
相同,对吗

同样地,以下从自身角度定义了
i
j

ghci> (i,j) = (j,i)

您可以使用GHCi在隐式IO do块中运行的属性,以及do绑定中的变量不在其右侧的作用域中的属性:

(i, j) <- return (j, i)

(i,j)它与惰性计算(本身)无关。您只需创建循环引用:
i
指向
j
j
指向
i
。第一个语句没有任何影响,因为在Haskell变量不能更改中,您构建了新的变量。因为正如前面所说,从您编写类似于
(i,j)=(j,i)
的代码的那一刻起,头部就出现了变量,这些变量是局部范围的。因此,您创建了新变量
i
j
。因此,第一行没有任何影响。在Haskell中,
=
不是赋值运算符,而是一个声明。如果定义
阶乘n=如果n==0,那么1个其他n*(阶乘(n-1))
,您希望在RHS上使用的
阶乘与在LHS上使用的相同,对吗?同样地,
(i,j)=(j,i)
从自身的角度定义了
i
j
。如果你真的不想寻找赋值,那么你可以给新变量起新名字来避免问题:
(i2,j2)=(j,i)
。这可能不是非常有用,所以我们可能需要更多的上下文。