Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self-referential data type with single constructor cannot be `Show`n

This is from The Little MLer. I have this

data Chain = Link Int (Int -> Chain)

and this

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

I'm rather confused as to what exactly is happening here. It seems like an endless recursion of itself where intson the left-hand side is just repeating the whole ints endlessly. The book is saying

[...] we may think of ints as a very long sequence of ints. We go from one element in this sequence to the next by applying the second component of ints n to the first.

I'm not sure how it does this. But then this produces an error

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

An attempt to tack on deriving Show won't fly

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)

Not sure what is going on or how to proceed. Any similar examples would be appreciated.


Update

Here's the SML code

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

Not totally sure, but that fn is the SML way of doing anonymous, i.e. fn is their \. This might just be a coincidence.

So what's SML got that Haskell can't handle? Is this something to do with Haskell being pure and SML is not?

like image 661
147pm Avatar asked Dec 23 '22 15:12

147pm


1 Answers

In general there is no good way to Show a function, so Haskell will not make an instance of Show for you when a function is involved..

You could write one yourself:

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

But now you have to figure out how to show fn:: Int->Chain. In Haskell at least functions are atomic and opaque. You can't break them apart or inspect their contents, only apply them.

like image 143
John F. Miller Avatar answered Apr 27 '23 12:04

John F. Miller