具有单个构造函数的自引用数据类型不能为 `Show`n

147*_*7pm 4 haskell types sml self-reference

这是来自The Little MLer。我有这个

data Chain = Link Int (Int -> Chain)
Run Code Online (Sandbox Code Playgroud)

和这个

ints :: Int -> Chain
ints n = Link (n+1) ints
Run Code Online (Sandbox Code Playgroud)

我对这里到底发生了什么感到很困惑。这似乎是自身的无限递归,ints左侧只是ints无休止地重复整个过程。书上说

[...] 我们可以认为ints是一个很长的ints. 通过将 的第二个组件应用于第一个,我们从这个序列中的一个元素到下一个元素ints n

我不确定它是如何做到的。但是这会产生一个错误

> ints 0
* No instance for (Show Chain) arising from a use of `print'
:     * In a stmt of an interactive GHCi command: print it
Run Code Online (Sandbox Code Playgroud)

尝试加入deriving Show不会成功

data Chain = Link Int (Int -> Chain) deriving Show
No instance for (Show (Int -> Chain))
        arising from the second field of `Link' (type `Int -> Chain')
        (maybe you haven't applied a function to enough arguments?)
      Possible fix:
        use a standalone 'deriving instance' declaration,
          so you can specify the instance context yourself
    * When deriving the instance for (Show Chain)
Run Code Online (Sandbox Code Playgroud)

不确定发生了什么或如何进行。任何类似的例子将不胜感激。


更新

这是 SML 代码

datatype chain = Link of (int * (int -> chain))
fun ints (n) = Link (n+1, ints)
> ints(0)
val it = Link (1,fn) : chain
Run Code Online (Sandbox Code Playgroud)

不完全确定,但这fn是匿名的 SML 方式,即fn是他们的\. 这可能只是一个巧合。

那么 SML 有哪些 Haskell 无法处理的东西呢?这与 Haskell 是纯粹的而 SML 不是有关吗?

Joh*_*ler 7

一般来说,函数没有好的方法Show,所以Show当涉及到函数时,Haskell 不会为你创建一个实例。

你可以自己写一个:

instance Show Chain where
  show (Link n fn) = ...
Run Code Online (Sandbox Code Playgroud)

但是现在您必须弄清楚如何显示fn:: Int->Chain. 在 Haskell 中,至少函数是原子的和不透明的。您不能将它们拆开或检查它们的内容,只能应用它们。