2

I wrote the following code.

sqrSum x = sum . map (^2) $ [1..x]

mbFact x
    | x < 0 = Nothing
    | otherwise = Just . product $ [1..x]

main =
    let --print' :: (Show a) => a -> IO () -- why need this?
        print' =
            putStrLn . show
    in  do
        print' $ mbFact (-11)
        print' $ mbFact 0
        print' $ sqrSum 3

If I uncomment the "why need this?" line the code compiles and works.

After commenting that line, I expected the Haskell compiler to infer the type of print'. But it didn't. Why?

error:
    * Ambiguous type variable `a0' arising from a use of `show'
      prevents the constraint `(Show a0)' from being solved.
      Relevant bindings include
        print' :: Maybe a0 -> IO () (bound at b.hs:9:9)
      Probable fix: use a type annotation to specify what `a0' should be.
      These potential instances exist:
        instance Show Ordering -- Defined in `GHC.Show'
        instance Show Integer -- Defined in `GHC.Show'
        instance Show a => Show (Maybe a) -- Defined in `GHC.Show'
        ...plus 22 others
        ...plus 13 instances involving out-of-scope types
        (use -fprint-potential-instances to see them all)
    * In the second argument of `(.)', namely `show'
      In the expression: putStrLn . show
      In an equation for print': print' = putStrLn . show
   |
10 |             putStrLn . show
   |                        ^^^^

Why can't GHC infer the type of print'?

  • 8
    [This is the monomorphism restriction.](https://stackoverflow.com/questions/32496864/what-is-the-monomorphism-restriction) GHC *can* successfully infer this type (check in GHCi), but there's an unfortunate rule in the language that breaks it (`print'` "looks like" a variable, not a function, and making a variable polymorphic can be a performance loss, so variables are monomorphized in an attempt to avoid performance mistakes). GHCi has `-XNoMonomorphismRestriction` set by default for a better interactive experience, but GHC does not. I thought there were plans to just get rid of it... – HTNW Aug 10 '20 at 11:52
  • @HTNW you should make that an answer! – MLavrentyev Aug 10 '20 at 14:22
  • [see also](https://stackoverflow.com/questions/63295758/trying-to-understanding-why-this-function-using-foldr-in-haskell-isnt-working/63299276#comment111939341_63299276). – Will Ness Aug 10 '20 at 15:00

0 Answers0