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):

enter image description here

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 tip ghci>

    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 a insertWith (++)

    starter battery, which is a card empty

    . The function is as follows (same as the second prompt ghci>

    in the screenshot above) (see the second prompt ghci>

    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 name foldingFunc

    ) that was equal to flip $ uncurry (Map.insertWith (++))

    . It's just the first argument foldl'

    in the above expression. (See the expression let

    in the third invitation ghci>

    above.)

  • This is where I got confused: as a normal check, I do the same foldl'

    as above, except foldingFunc

    (instead of flip $ 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?

+3


source to share


1 answer


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 use foldingFunction m = (flip $ uncurry (Map.insertWith (++))) m

    or maybe better foldingFunction 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 :)

+8


source







All Articles