Haskell: expression of “generic” type
-
29-06-2021 - |
Question
In a similar problem as the one showed in this question, is it possible to have a Haskell expression of "generic" type a? Something like,
myExpression :: a
I'm new to Haskell, but from what i've been seeing this cannot be achieved.
Solution
No, there is nothing that satisfies that other than bottom, e.g.
myExpression = myExpression
-- or,
myExpression = undefined
Is there any reasonable way that it could be possible? Some non-bottom expression that is both an Integer
and of type Maybe (String -> IO ())
(for example).
Furthermore, given the question you mention, one answer of which proved that the only non-bottom function with type signature a -> a
is id
, we have a proof that there can't be a non-bottom expression with type a
. If there was, then
f _ = myExpression
could have type a -> a
, and this is neither id
nor bottom, i.e. a contradiction.
OTHER TIPS
You can read that type signature as "for all types a, myExpression is of type a". That means myExpression must be some value that exists in all types.
Mathematically speaking, no such value exists, since a could be "Badgers" or "Things that are not badgers", and these two sets are necessarily distinct.
In the Haskell type system, the only valid value for myExpression to take is undefined, aka bottom.
While abstractly there is only one value that has type "a", bottom, there are a variety of possible interpretations at runtime.
myExpression = myExpression
This will never terminate.
myExpression = undefined
This will (when using GHC) print "* Exception: Prelude.undefined"
myExpression = error "Hello!
This will print "* Exception: Hello!"
myExpression = unsafePerformIO (launchNukes >> fail "BOOM")
The behavior of this version of bottom depends on which libraries you've imported.
Since you ask about a "generic" type, you might mean the type of things that can usefully contain any value. In that case, take a look at Data.Dynamic, which allows you to convert anything that has an in-memory representation to a value of type "Dynamic". Later, when consuming a value of type "Dynamic", you can attempt to turn it into a more specific type that you can actually do something useful with.