一行 Haskell 中的 Thue-Morse 序列

Thue-Morse Sequence in one Line of Haskell

我在 Haskell 的一行中为 Thue-Morse squence 写了一个无限整数列表的定义:

thueMorse = 0:1:f (tail thueMorse) where f = (\(x:xs) -> x:(1 - x):f xs)

这是尝试在一行中定义序列失败的结果,仅根据 lambda 表达式及其本身,没有 let 或 where 表达式(实际上应该在两行中呈现,使上述解决方案精神上的两个班轮)。我一直在阅读有关 lambda 演算的一些内容,所以我想我会尝试将其作为练习。我想知道在 Haskell 中是否可以做这样的事情,如果可能的话如何做。

thueMorse = 0:1:(\f xs -> f f xs) (\f (x:xs) -> x:(1 - x):f f xs) ((\(_:xs) -> xs) thueMorse)

上面的表达式有点难读,所以我将其分解:

(\f xs -> f f xs)

接受一个函数和一个参数,并将该函数应用于自身和参数。 Haskell 不会计算这个表达式,因为 f 的类型是 t = t -> a -> a,这是我问题的症结所在。

(\f (x:xs) -> x:(1 - x):f f xs)

是传递给前一个表达式的函数,它将自身和一个列表作为参数。这是递归计算 Thue-Morse 序列的部分。这也有一个无限类型 t = t -> [a] -> [a].

((\(_:xs) -> xs) thueMorse)

这相当于(tail thueMorse),但是用lambda表达式来写以满足练习条件。

Haskell 抱怨这些表达式具有无限类型并拒绝对它们求值,我认为如果对它们求值,它们会正确生成 Thue-Morse 序列。有什么方法可以扭曲解释器或编译器的手臂来评估这些表达式吗?有没有一种方法可以调整语句,使其可以被评估,但仍然只使用来自 lambda 演算的运算符,并且在一行中?

这是相同的算法,但没有显式 fix:

thueMorse = 0 : 1 : (tail thueMorse >>= \x -> [x, 1 - x])