Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Has anyone ever compiled a list of the imports needed to avoid the "not polymorphic enough" definitions in Haskell's standard libraries?

Tags:

I have been using Haskell for quite a while. The more I use it, the more I fall in love with the language. I simply cannot believe I have spent almost 15 years of my life using other languages.

However, I am slowly but steadily growing fed up with Haskell's standard libraries. My main pet peeve is the "not polymorphic enough" definitions (Prelude.map, Control.Monad.forM_, etc.). I have a lot of Haskell source code files whose first lines look like

{-# LANGUAGE NoMonomorphismRestriction #-}  module Whatever where  import Control.Monad.Error hiding (forM_, mapM_) import Control.Monad.State hiding (forM_, mapM_) import Data.Foldable (forM_, mapM_)  {- ... -} 

In order to avoid constantly hoogling which definitions I should hide, I would like to have a single or a small amount of source code files that wrap this import boilerplate into manageable units.

So...

  1. Has anyone else tried doing this before?
  2. If the answer to the previous question is "Yes", have they posted the resulting boilerplate-wrapping source code files?
like image 746
pyon Avatar asked Jun 18 '12 01:06

pyon


1 Answers

It is not as clear cut as you imagine it to be. I will list all the disadvantages I can think of off the top of my head:

First, there is no limit to how general these functions can get. For example, right now I am writing a library for indexed types that subsumes ordinary types. Every function you mentioned has a more general indexed equivalent. Do I expect everybody to switch to my library for everything? No.

Here's another example. The mapM function defines a higher order functor that satisfies the functor laws in the Kleisli category:

mapM return = return mapM (f >=> g) = mapM f >=> mapM g 

So I could argue that your traversable generalization is the wrong one and instead we should generalize it as just being an instance of a higher order functor class.

Also, check out the category-extras package for some examples of these higher order classes and functions which subsume all your examples.

There is also the issue of performance. Many of thesr more specialized functions have really finely tuned implementations that dramatically help performance. Sometimes classes expose ways to admit more performant versions, but sometimes they don't.

There is also the issue of typeclass overload. I actually prefer to minimize use of typeclasses unless they have sound laws derived from theory rather than convenience. Also, typeclasses generally play poorly with the monomorphism restriction and I enjoy writing functions without signatures for my application code.

There is also the issue of taste. A lot of people simply don't agree what is the best Haskell style. We still can't even agree on the Prelude. Speaking of which, there have been many attempts to write new Preludes, but nobody can agree on what is best so we all default back to the Haskell98 one anyway.

However, I think the overall spirit of improving things is good and the worst enemy of progress is satisfaction, but don't assume there will be a clear-cut right way to do everything.

like image 61
Gabriella Gonzalez Avatar answered Nov 05 '22 13:11

Gabriella Gonzalez