Type class instances may only be defined for "real" types, as defined by a data
or newtype
declaration. A type
declaration is a "fake" type—just an abbreviation for a longer type.
But that's just problem #1 in this case. Problem #2 is that even if you do this...
newtype Function = Function (Argument -> Store -> Value)
...there might still be no truly useful Show
instance for Function
. How do turn a function into a string? There are two strategies. First, the "just give up" strategy:
instance Show Function where
show _ = "<some Function, no clue what it does>"
Second, the "canonical example" strategy, where you apply the Function
to some canonical Argument
and Store
and show these together with the Value
result:
instance Show Function where
show (Function fn) = "Function: "
++ show defaultArgument
++ " -> "
++ show defaultStore
++ " -> "
++ show (fn defaultArgument defaultStore)
The idea here is to display the Function
as one particular argument/value mapping of it that might help you identify it more precisely than just using the same constant string for all of them. Whether this helps or not depends on what your functions do.
But now we have problem #3: neither of these obeys the intent/contract of the Show
and Read
classes, which is that read (show x)
is equivalent to x
. (People do often ignore this intent, however, just because they want to print something and Show
is the quickest ticket. So much that, as Thomas DuBuisson points out, there's a standard module Text.Show.Functions
that implements the "just give up" strategy.)
As for the Eq
class, the answer is that it's just impossible in general to compare two functions for equality. (If I recall correctly, it's equivalent to solving the Halting Problem, but don't quote me on that.) If your solution requires you to compare functions for equality, you need a new solution...