As Thomas said, the value of Int or Int->Int->Int cannot be of the Token type: each Haskell value has exactly one type 1 there is no such thing as subtyping the OO style in Haskell.
However, Haskell types (not just functions, but all!) Can be polymorphic. Indeed, numeric literals are polymorphic:
Prelude>: t 12
12 :: Num a => a
This means that if Token is a type of Num , then 12 will be actually the correct value (it will not be of type Int , and then Token right away!). For this you can write
instance Num Token where fromInteger = Token . fromInteger
Strictly speaking, then you should also implement add, absolute value, etc. for Token , which doesnβt work out very nicely. In addition, (+) is still not valid in [Token] . But you could write
tokens = [12, Operator(+)]
In fact, if this should be a very long list, and you want the code to be short, you could resort to a rather nasty trick that would allow you to write it exactly as you originally did:
mkToken :: TokenRep -> Token mkToken f = f undefined undefined type TokenRep = Token->Token->Token instance Num Token where _ + _ = Operator (+) _ - _ = Operator (-) _ * _ = Operator (*) instance Num TokenRep where -- You need `-XFlexibleInstances` here fromInteger n _ _ = Value $ fromInteger n
and then
tokens = map mkToken [12, (+)] -- Note that `12` has type `Token->Token->Token` here!
But actually it would be a terrible hack.
1 One type can have more than one name: [Char] and String are actually the same type, the latter is simply defined as a synonym for type String = [Char] . OTOH, with data or newtype you always define a new (duh) and therefore a separate type.