Reputation: 3
I have difficulty understanding type creation in Haskell. I am trying to understand why the following Haskell function returns a type instead of a value:
data Exp = Enum Int
data Val = Vnum Int
eval :: Exp -> Val
eval (Enum x) = Vnum x
x :: Exp
x = Enum 2
When I run 'eval x', instead of returning 2 as I would expect, the interpreter returns 'eval x :: Val'. Enum and Vnum are merely tags, so basically, the eval function takes an "expression" as argument, which is in fact merely an integer, and returns a "value", which is also nothing more than an integer.
Like, of course eval x returns a Val, but why does the function not actually calculate the value and return it? I have the impression that the answer in kind of right in my face, but at the same time, I must be missing some elementary concept which is preventing me from noticing something that is probably obvious.
Thanks in advance for your help!
Upvotes: 0
Views: 273
Reputation: 120751
Why does my Haskell function return a type
it doesn't. Your function works just fine and eval x
does indeed give a value of type Val
.
However note that an interpreter has no way to display this value – as far as it is concerned, this is a completely opaque type. At least GHCi makes this pretty clear:
<interactive>:3:1: error:
• No instance for (Show Val) arising from a use of ‘print’
• In a stmt of an interactive GHCi command: print it
Only if you say that you're really only interested in the type, by using the :t
or :type
directive, will it show just that:
> :t eval (Enum 2)
eval (Enum 2) :: Val
The easiest way to enable printing of values is to derive a Show
instance:
data Val = Vnum Int -- incidentally, this should probably be `newtype`,
deriving (Show) -- rather than `data`
> eval (Enum 2)
Vnum 2
Upvotes: 11