Haskell often provides two versions of a given function f, i.e:
f :: Int ...
genericF :: Integral i => i ...
There exist many standard library functions with those two versions: length, take, drop, etc.
Quoting the description of genericLength
:
The genericLength function is an overloaded version of length. In particular, instead of returning an Int, it returns any type which is an instance of Num. It is, however, less efficient than length.
My question is: where does the efficiency loss comes from? Can't the compiler detect that we are using genericLength
as an Int and therefore us length
for better performance? Why isn't length
generic by default?
Best Answer
It's the same reason as why we have
map
andfmap
. Error messages/usability for newbies.It'd by mighty confusing for many a new programmer to write
and get an error complaining about the monomorphism restriction. Plus which do you prefer
or
It's simply a matter of usability.
Furthermore, in a lot of cases you end up just wanting defaulting anyways, such as with function composition
vs
Here we just want GHC to "pick" a random
Num
type and we really don't care which (it'sInteger
IIRC).If everything was fully generic the defaulting rules would get um.. murky. Since As of right now there are only 4 things that are automatically available as defaults and no way to set anything fine grained (per function).
As for efficiency, typeclasses means lugging potentially lugging typeclass's dictionary and defaulting to
Integer
which is much more expensive thanInt
.There are alternative preludes (I think classy prelude is unmaintained, but interesting) that do attempt to be as generic as possible. Using them is as simple as