Haskell: function composition resulted in a type mismatch error
TL; DR: What can cause a type mismatch error in GHCi just as a result of function composition? It's odd to see GHCi evaluating the following code:
foldl (a . b . c) crackle pop <- GHCi evaluates this`
... just to give an error after we try to evaluate the following:
let snap = a . b . c <- GHCi evaluates this
foldl snap crackle pop <- GHCi reports an error (!)
Longer version:
I am puzzled by what I observe here at GHCi and I hope someone can explain it (description included below):
What do we see above?
-
First, we have a variable
b
that is tied to the following list:[(2,["Dipak"]), (2,["Andrew"]),(2,["Keone"])]
.b
has a type[(Int,[String])]
. (See the first tipghci>
and final result in the screenshot above.) -
Then perform a bend on
b
, transforming it into the following type:Map (Integer, [String])
. We do this using a folding function based on ainsertWith (++)
starter battery, which is a cardempty
. The function is as follows (same as the second promptghci>
in the screenshot above) (see the second promptghci>
above.)foldl' (flip $ uncurry (Map.insertWith (++))) (Map.fromList []) b
-
Nice cool; so far, so good
-
Considering the function
foldl'
above was mouth-watering, I decided to compose a flex function (with a namefoldingFunc
) that was equal toflip $ uncurry (Map.insertWith (++))
. It's just the first argumentfoldl'
in the above expression. (See the expressionlet
in the third invitationghci>
above.) -
This is where I got confused: as a normal check, I do the same
foldl'
as above, exceptfoldingFunc
(instead offlip $ uncurry (Map.insertWith (++))
), which should just be a cosmetic change ... and now GHCi is reporting a type mismatch error (details above).
Can someone please help me understand why in this case the composition function resulted in an error (as a result of the type change)? And what should I do differently?
source to share
Dynamic duo ghci expands default rules and strike with Restricted Monomorphism again!
I am assuming you are using a slightly outdated ghci, version 7.6 or earlier.
What happens is what's the foldingFunction
most general type
foldingFunction :: Ord a => Map a [b] -> (a,[b]) -> Map a [b]
However , since this is a top-level definition with no arguments, and your version of ghci still has the monomorphism constraint, this is not a "good" type (it is polymorphic due to context Ord a
), and the default rules are triggered. ghci tries to find a default instance for Ord a
- usually it won't work (since there is no limit Num
), but ghci also considers ()
a possible default.This works, so if you ask ghci about the type foldingFunction
, you get
foldingFunction :: Map () [b] -> ((), []) -> Map () []
where your type error comes from. (I hope I understood correctly!)
There are several ways:
- Add an argument to
foldingFunction
: if you usefoldingFunction m = (flip $ uncurry (Map.insertWith (++))) m
or maybe betterfoldingFunction m (a,bs) = insertWith (++) a bs m
it will start working. - Disable the restriction of monomorphism by adding the right-hand side to the top of the file,
{-# LANGUAGE NoMonomorphismRestriction #-}
or interactively by typing:set -XNoMonomorphismRestriction
ghci at the command line. - Upgrading to a newer version of GHC (7.8.3 does the trick for me).
Both of which have a default DMR, and the default extended rules are fairly recent (last couple of years) additions to ghci, so it may turn out that the book or text you are using is too old :)
source to share