0
import qualified Data.Map as Map

solve :: Ord a => Map.Map a a -> [(a,a)] -> String
solve _ [] = "YES"
solve hash (x:xs)  
  | Map.member (fst x) hash = "NO"
  | otherwise = solve (Map.insert (fst x) (snd x) hash) xs 

solve1 = solve Map.empty

This gives the following error:

 main.hs:13:10: error:

 * Ambiguous type variable `a0' arising from a use of `solve'
  
 prevents the constraint `(Ord a0)' from being solved.
  
 Relevant bindings include
    
 solve1 :: [(a0, a0)] -> String (bound at main.hs:13:1)
  
 Probable fix: use a type annotation to specify what `a0' should be.
  
 These potential instances exist:
    
 instance (Ord a, Ord b) => Ord (Either a b)
 
 -- Defined in `Data.Either'

    instance (Ord k, Ord v) => Ord (Map.Map k v)

      -- Defined in `Data.Map.Internal'

    instance Ord Ordering -- Defined in `GHC.Classes'

    ...plus 24 others

    ...plus 44 instances involving out-of-scope types

    (use -fprint-potential-instances to see them all)

* In the expression: solve Map.empty

  In an equation for `solve1': solve1 = solve Map.empty

I read a bunch of answers related to this here on stack overflow but it still wasn't quite clear. All of them stated the problem and the explanation but didn't list the possible fixes/workarounds. Or maybe I am too of a newbie to infer the solution on my own.

Any help would be appreciated.

Tony
  • 81
  • 9
  • 1
    When you run into an issue like this, you should always give all your top-level definitions explicit type signatures. In fact, you should do that regardless. Also, the error message seems to indicate that the error is in `solve2` which is not in the code in the question. – David Young Jun 18 '22 at 14:36
  • @DavidYoung My apologies... I was experimenting with the code and trying figure out what works. I shall edit the error message to fit in with the actual code. – Tony Jun 18 '22 at 14:43
  • Okay it worked when I gave solve1 its type signature `solve1 :: Ord a => [(a,a)] -> String` But why did the type inference fail here? – Tony Jun 18 '22 at 14:51
  • 2
    This is the result of the monomorphism restriction, see https://stackoverflow.com/q/32496864 – Noughtmare Jun 18 '22 at 15:02
  • As @DavidYoung says, you should always give your top level definitions their type signatures. Otherwise when you get a type error all the compiler knows is that the a bunch of definitions contain a type error somewhere. The error message contains its best guess, but the actual error may well be somewhere else. If you say what you think the type of each thing should be, that lets the compiler identify exactly where the inconsistency comes from. – Paul Johnson Jun 18 '22 at 15:49

0 Answers0