Haskell type variables are universally evaluated, so Integral b => b not only means some type of Integral , it means any type of Integral . In other words, the caller chooses which specific types to use. Therefore, it is obvious that the error type always returns Int when the type signature says that I should select any Integral type, for example. Integer or Word64 .
There are extensions that allow you to use existentially quantified type variables , but they are more cumbersome to work because they require a shell type (to store a type dictionary). In most cases, it is best to avoid them. But if you want to use existential types, it will look something like this:
{-
Code using this function should then be polymorphic enough to work with any type of Integral . We must also match patterns using case instead of let so that the GHC brain does not explode.
> case f True of SomeIntegral x -> toInteger x 3 > :t toInteger toInteger :: Integral a => a -> Integer
In the above example, you might think that x is of type exists b. Integral b => b exists b. Integral b => b , i.e. the unknown type is Integral .
source share