Home > Software engineering >  No instance for (Show NP) arising from a use of ‘show’
No instance for (Show NP) arising from a use of ‘show’

Time:11-23

I'm really new to Haskell so your help would be much appreciated!

As a small training task I created this function in Haskell and tried to run it:

data S = S NP VP 
data N = Linguist | Chemist | Anglist | N ADJ N
data NP = NP DET N
data ADJ = Curious | Smart
data DET = The | Some | Every
data VP = Snores | Dreams | V NP
data V = Cites | Corrects
np :: NP
np = NP Every (N Smart (N Curious Linguist))

When calling it, I get this error:

*Main> np

<interactive>:58:1: error:
    • No instance for (Show NP) arising from a use of ‘print’
    • In a stmt of an interactive GHCi command: print it

I expected this output: NP Every (N Smart (N Curious Linguist))

Has anyone an idea what to do and why? I just copied the code from a powerpoint presentation where it was used as an example and did everything exactly as mentioned on the slide. Thank you very much for your help!

CodePudding user response:

Not all types can be shown. The standard example are functions – how could you possibly represent these? (Neither listing all possible input-output pairs nor rattling down the entire source code is feasible or useful.)

Also, some types can be shown but you don't want it to be in the generic form of constuctor nestings but rather something application-specific. For instance, Map is defined as a Haskell type with strange constructors and internal implementation details that most users of the library don't care about. So the show/print methods for Map hide all that, and present a Map instead by all the key-value pairs:

ghci> import Data.Map as M
ghci> M.union (M.fromList [('a',2), ('b',4), ('y',9)]) (M.fromList [('m',13)])
↦ fromList [('a',2),('b',4),('m',13),('y',9)]

But it wouldn't possible for the compiler to just guess that this is the form in which you want to show Maps.

For these reasons, you always need to enable showing of a type's values explicitly. In general that requires defining a Show instance, like

instance Show NP where
  show (NP d n) = "NP ("  show d  ") ("  show n  ")" -- not recommended

But the case where show should just directly reflect the type's tree structure, which you do seem to want here, can of course be handled automatically by the compiler, you just need to ask for it. This is the behaviour you get from deriving the instance, which is what you should probably do for all these types:

data S = S NP VP deriving (Show)
...
data NP = NP DET N deriving (Show)
...

While you're at it, you might as well also add Eq and Read, just in case:

data S = S NP VP deriving (Eq, Show, Read)
...
data NP = NP DET N deriving (Eq, Show, Read)
...

CodePudding user response:

data S = S NP VP deriving Show
data N = Linguist | Chemist | Anglist | N ADJ N deriving Show
data NP = NP DET N deriving Show
data ADJ = Curious | Smart deriving Show
data DET = The | Some | Every deriving Show
data VP = Snores | Dreams | V NP deriving Show
data V = Cites | Corrects deriving Show
  • Related