首页 > 解决方案 > 具有单个构造函数的自引用数据类型不能是 `Show`n

问题描述

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

data Chain = Link Int (Int -> Chain)

还有这个

ints :: Int -> Chain
ints n = Link (n+1) ints

我对这里到底发生了什么感到困惑。它似乎是自身的无休止递归,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

试图继续前进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)

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


更新

这是 SML 代码

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

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

那么SML 有什么Haskell 无法处理的呢?这与 Haskell 是纯的而 SML 不是有关吗?

标签: haskelltypessmlself-reference

解决方案


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

你可以自己写一个:

instance Show Chain where
  show (Link n fn) = ...

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


推荐阅读