

Line 1: 
Line 1: 
−  If you are new to Haskell you may think that type variables and [[polymorphism]] are fancy things that are rarely used.
 
−  Maybe you are surprised that type variables and [[type class]] constraints can increase safety and readability
 
−  also if you are eventually using only one concrete type.
 
   
−  Imagine the [[Prelude]] would contain the following functions:
 
−  <haskell>
 
−  maximum :: [Integer] > Integer
 
−  sum :: [Integer] > Integer
 
−  </haskell>
 
−  Sure, the names are carefully chosen and thus you can guess what they do.
 
−  But the signature is not as expressive as it could be.
 
−  Indeed these functions are in the Prelude but with a more general signature.
 
−  <haskell>
 
−  maximum :: (Ord a) => [a] > a
 
−  sum :: (Num a) => [a] > a
 
−  </haskell>
 
−  These functions can also be used for <hask>Integer</hask>s,
 
−  but the signatures show which aspects of integers are actually required.
 
−  We realize that <hask>maximum</hask> is not about numbers, but can also be used for other ordered types, like <hask>Char</hask>.
 
−  We can also conclude that <hask>maximum []</hask> is undefined,
 
−  since the <hask>Ord</hask> class has no function to construct certain values and the input list does not contain an element of the required type.
 
− 
 
− 
 
−  Now consider that you have a complex function that is hard to understand.
 
−  It is fixed to a concrete type, say <hask>Double</hask>.
 
−  You want to divide that function into a function that does the processing of the structure
 
−  and another function which does the calculations with <hask>Double</hask>.
 
−  This is good style in the sense of the "[[Separation of concerns]]" idiom.
 
−  You do it, because you want to untangle the [[Things_to_avoid#Avoid_explicit_recursionexplicit recursion]],
 
−  which is hard to understand of its own,
 
−  and the calculation, which also has pitfalls.
 
−  The structure processing does not know about the <hask>Double</hask>
 
−  and it is wise to use type variables instead of <hask>Double</hask>
 
− 
 
−  Making the example more concrete, look at a state monad transformer <hask>StateT</hask>
 
−  which shall be nested by a nesting depth that is only known at runtime.
 
−  Ok that's not possible, so just consider a <hask>State</hask> [[applicative functor]], that shall be nested the same way.
 
−  The functor depends on an input of the same type as its functor output,
 
−  that is we nest functions of type <hask>(Double > State Double Double)</hask>.
 
−  The nested functor has a list of state values as state value.
 
−  The nesting depth depends on the length of the list of state values.
 
−  (This design also forbids transformer techniques for general applicative functors.)
 
−  We could write a nesting function fixed to type <hask>Double</hask>
 
−  <haskell>
 
−  stackStates :: (Double > State Double Double) > (Double > State [Double] Double)
 
−  </haskell>
 
−  but it is too easy to mix up state and return value here, because they have the same type.
 
−  You should really separate that
 
−  <haskell>
 
−  stackStates :: (a > State s a) > (a > State [s] a)
 
−  stackStates m = State . List.mapAccumL (runState . m)
 
−  </haskell>
 
−  also if you only use it for <hask>Double</hask>.
 
−  This way the type checker asserts, that you never mix up the state with the other type.
 
− 
 
− 
 
−  [[Category:Style]]
 
−  [[Category:Idioms]]
 