Heinrich Apfelmus apfelmus at quantentunnel.de
Tue Aug 18 06:35:18 EDT 2009

```Michael Mossey wrote:
> Heinrich Apfelmus wrote:
>> This would be an example where I think that the Reader monad is an
>> implementation detail, not a model of the problem domain. (Not to
>> mention that I think that the Reader monad has very limited
>> applications.) The latter would be about trying to eliminate the need
>> for a context altogether, to group the many details so that they
>> can be
>> "polymorphized away", etc.
>
> Can you explain more about what it means to "polymorphize away"
> details? I'm not clear about that.
>
> You mention "grouping" details. Does this mean creating data which
> types that hold all the details, and the data type itself is some
> kind of larger concept? For example, you could say a note has many
> details such as time, duration, dynamic, etc. And you could also
> create
>
> data Note = Note { time :: Ratio, duration :: Ratio, dyn :: Dynamic }
>
> and work with Notes as much as possible without peering inside them.

Yes, the goal is to avoid peering inside. Creating a new abstraction
(= no peeking inside) is the only way to make things elegant. Using
record data types are a first step towards that goal.

Another technique is to use parametric polymorphism, that's what I
intend to convey with the phrase "polymorphize away". The idea is
that the type system can make sure that you don't peek inside.
Consider the following (almost too trivial) example:

length :: [Note] -> Int

This function is intended to calculate the length of a list of notes.
But of course, it's wholly unimportant that the lists consists of
notes, it could as well be a list of apples or integers. In fact, the
specialization to notes is a mental burden, and it's much simpler to
write a length function that does not care about the contents

length :: [a] -> Int

The key point is that the type alone already ensures that  length
*cannot* peek inside the list elements, because it's polymorphic in  a .

Another example is the function

sortBy :: (a -> a -> Ordering) -> [a] -> [a]

which does not want to know anything about the list elements except
that they can be compared.

Of course, these were rather general and well-known examples; the key
is to find similar patterns in your own code and problem domain. For
instance, notes in staff notation don't really care about velocities,
notes in a piano roll are actually just rectangles in a grid, etc.
The goal is to focus solely on the relevant details and hide the
unimportant details behind a type variable  a .

Regards,
apfelmus

--
http://apfelmus.nfshost.com

```