1

Why this code does not compile with an Ambiguous type variable error

foo :: (Show a) => a -> IO ()
foo = putStrLn . show
bar = foo

whereas in the GHCI the following commands work fine?

> let foo :: (Show a) => a -> IO (); foo = putStrLn . show
> bar = foo
> bar 1

Why do we need an explicit type annotation for the bar function?

xafizoff
  • 398
  • 1
  • 13
  • 3
    Looks like the monomorphism restriction, which is enabled in GHC but disabled in GHCi for extra convenience. https://stackoverflow.com/questions/32496864/what-is-the-monomorphism-restriction – chi Sep 18 '18 at 08:20
  • `NoMonomorphismRestriction` fixes that. Thanks! – xafizoff Sep 18 '18 at 08:29
  • It would be helpful if the ghc suggested to enable this extension, but it doesn't in that case. – xafizoff Sep 18 '18 at 08:32
  • @xafizoff It would be good if you could write up what you have learned as an answer for the benefit of others. Thanks. – Paul Johnson Sep 18 '18 at 08:35
  • 1
    @xafizoff There are some downsides of turning it off, evaluating performance becomes more tricky, since some constants now are disguised functions and get recomputed every time. Usually one keeps MR on, and adds type signatures to `bar` like `bar :: (Show a) => a -> IO ()`. Or, less commonly, writes `bar x = foo x`. – chi Sep 18 '18 at 09:33
  • 2
    @xafizoff For the most part, what you wanna do is to give explicit type signatures in your source files - that's good for documentation purposes anyway (you'd be surprised how little you remember about what your own code does within a week or two) – Cubic Sep 18 '18 at 10:18

0 Answers0