Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I always prefer more general types to specific types?

Compiled with ghc --make, these two programs produce the exact same binaries:

-- id1a.hs
main = print (id' 'a')

id' :: a -> a
id' x = x

-- id1b.hs
main = print (id' 'a')

id' :: Char -> Char
id' x = x

Is this just because of how trivial/contrived my example is, or does this hold true as programs get more complex?

Also, is there any good reason to avoid making my types as general as possible? I usually try keep specifics out where I don't need them, but I am not extremely familiar with the effects of this on compiled languages, especially Haskell/GHC.

Side Note:

I seem to recall a recent SO question where the answer was to make a type more specific in order to improve some performance issue, though I cannot find it now, so I may have imagined it.

Edit:

I understand from a usability / composability standpoint that more general is always better, I'm more interested in the effects this has on the compiled code. Is it possible for me to be too eager in abstracting my code? Or is this usually not a problem in Haskell?

like image 821
Adam Wagner Avatar asked Oct 05 '11 04:10

Adam Wagner


4 Answers

I would go and make everything as general as possible. If you run into performance issues you can start thinking about messing with concrete implementations but IMHO this will not be a problem very often and if this really gets an problem then maybe your performance need will be as great as to think about moving into imperative-land again ;)

like image 108
Random Dev Avatar answered Nov 17 '22 04:11

Random Dev


Is there any good reason to avoid making my types as general as possible?

No, as long as you have the Specialize pragma at your disposal for those rare situations where it might actually matter.

like image 24
Dan Burton Avatar answered Nov 17 '22 04:11

Dan Burton


Is this just because of how trivial/contrived my example is

Yes. Namely, try splitting the definition of id' and main into different modules and you should see a difference.

However, Carsten is right: there may be performance-related reasons to use concrete types, but you should generally start with general types and use concrete implementations only if you actually have a problem.

like image 43
Alexey Romanov Avatar answered Nov 17 '22 04:11

Alexey Romanov


General types usually make your functions more usable, in my opinion.

This may be a poor example, but if you're writing a function such as elem (takes a list and an element and returns true if the list contains that element and false otherwise), using specific types will constrain the usability of your function. ie. if you specify the type as Int, you can't use that function to check if a String contains a certain character, for example.

I'm not quite sure about performance, but I haven't experienced any issues and I use general types almost all the time.

like image 37
Sadiq Avatar answered Nov 17 '22 05:11

Sadiq