3

In the solution to another question, I came up with the following code, which type checks nicely:

import Control.Applicative
import Data.Foldable

tryCombination :: Alternative f => Int -> Int -> f (Int,Int)
tryCombination x y 
    | x * y == 20 = pure (x,y)
    | otherwise   = empty

result :: Alternative f => f (Int,Int)
result = asum [tryCombination x y | x <- [1..5], y <- [1..5]]

However, when I remove the type signature from result, ghc tells me about ambiguous type variables:

No instance for (Alternative f0) arising from a use of ‘asum’
The type variable ‘f0’ is ambiguous
Relevant bindings include
  result :: f0 (Int, Int) (bound at BreakLoop.hs:12:1)
Note: there are several potential instances:
  ...

It looks like ghc has almost completely inferred the correct type. So, why is it that this inference cannot be entirely completed?

What appears even stranger is the error message I get when I use the following partial type signature:

result :: Alternative f => f _

The message is:

No instance for (Alternative f) arising from a use of ‘asum’
Possible fix:
  add (Alternative f) to the context of
    the inferred type of result :: f (Int, Int)
...

Is there any reasonable explanation for this behavior or is it just a bug?

Community
  • 1
  • 1
  • Is this solved if you put `{-# LANGUAGE NoMonomorphismRestriction #-}` at the top of the file? – bennofs Apr 15 '15 at 12:52
  • @bennofs Yes it is. I just checked with GHC 7.10.1. Martin, mind if I close this as a duplicate of [this](http://stackoverflow.com/a/7055932/1651941) question? I'm starting a new effort to point all questions where the answer is the dreaded monomorphism restriction to the same post so hopefully people can find the solution to this problem without needing to ask a question. – bheklilr Apr 15 '15 at 12:55
  • However, I would still consider it a bug that the PartialTypeSignatures version does not work. – bennofs Apr 15 '15 at 12:56
  • The PartialTypeSignatures version works in combination with the NoMonomorphismRestriction, so everything seems fine. Thanks for your answers. @bheklilr: I don't mind if you close it now. – Martin Huschenbett Apr 15 '15 at 13:03
  • @bennofs You think that the type inference should be able to pick up the `Alternative` constraint without `NoMonormorphismRestriction`? Possibly, but judging from [this](https://www.fpcomplete.com/user/thomasw/new-in-ghc-7-10-partial-type-signatures) post holes in constraints get a little iffy. My guess is that partial type signatures are there just to give hints to the compiler, but it can't the right types without the extensions turned on that allow it to infer the right types. I wouldn't expect it to infer types that need `ScopedTypeVariables` without that extension enabled. – bheklilr Apr 15 '15 at 13:05
  • @bheklilr there is no problem inferring types, the compiler is able to do that just fine. In fact, with NoMonomorphismRestriction, it does infer the type. Also, there is no hole in the constraints in this case (the constraints don't have a hole, only the result type). The inferred type signature also does not need NoMonomorphismRestriction enabled. – bennofs Apr 15 '15 at 13:07
  • In fact, the reason for the monomorphism restriction is that it might duplicate work. But in this case, the programmer has explicitly specified that there the type should be generic, therefore the type signature already shows that it will duplicate work if used for different types. – bennofs Apr 15 '15 at 13:08
  • @bennofs Good point. Maybe there's already a bug open for this, or possibly it was designed this way for simplicity. – bheklilr Apr 15 '15 at 13:10

0 Answers0