4

The following is defined in my assignment:

type Rel a = Set (a,a)

complR :: Ord a => Set a -> Rel a -> Rel a
complR (Set xs) r = Set [(x,y) | x <- xs, y <- xs, not (inR r (x,y))]

The set type can be called like this for example: (Set [(1,2)]). When I try to call the function like this, I receive a ''Cannot infer instance'' error. I'm quite sure it is because of my call and because of the Rel a in specific. The inR is also defined in the assignment which I did not include here.

What am I doing wrong? I am calling it like this for example:

complR (Set [(5,4), (3,3)]) (Set [(1,3)])

Thank you!

Edit: I don't think the assignment is using Data.Set. I don't see that included. I see Data.List. I do see however that there is this: newtype Set a = Set [a] deriving (Eq,Ord). The type for inR is this: Ord a => Rel a -> (a,a) -> Bool. The files used in this assignment are http://www.cwi.nl/~jve/rcrh/REL.hs and http://www.cwi.nl/~jve/rcrh/SetOrd.hs.

The function complR is placed into the REL.hs file. The error I get when I call complR is:

ERROR - Cannot infer instance
*** Instance   : Num (b,a)
*** Expression : complR (Set [(5,4),(3,3)]) (Set [(1,3)])
  • 2
    Are you using `Data.Set`? Can you post the exact error message you're receiving? GHC's error messages are usually very useful and contain contextual information that helps to diagnose the problem. Can you include the type of `inR`? I assume it's something like `inR :: Ord a => Rel a -> (a, a) -> Bool`, but it's hard to be sure. – bheklilr Jun 30 '14 at 21:04
  • 3
    It also looks as if you're using some `Set` implementation that is defined as nothing more than `data Set a = Set [a]`, which means that constructing values using the `Set` constructor, as you've done here on the right hand side of `complR`'s definition will not ensure that it returns a true `Set`, which requires that no elements are repeated. Is this also defined in your assignment for you? If so, please include the definition for `Set` since it's pretty hard to figure out what's wrong without it. – bheklilr Jun 30 '14 at 21:09
  • 1
    Thanks for your comment! I don't think the assignment is using Data.Set. I don't see that included. I see Data.List. I do see however that there is this: newtype Set a = Set [a] deriving (Eq,Ord). The type for inR is this: Ord a => Rel a -> (a,a) -> Bool (exactly like you said) –  Jun 30 '14 at 21:13
  • 2
    @user3791741 bheklilr is right - all your relevant code so far should be in your question, including the _exact_ error message, copied and pasted from the screen. – AndrewC Jun 30 '14 at 21:15
  • Thank you AndrewC. You are right. I included more information in the post. I hope it is more clear. –  Jun 30 '14 at 21:23
  • That's great, thanks. Have you got the error message too to paste in? – AndrewC Jun 30 '14 at 21:23
  • I pasted the error message below the main post. It happens when I call the function like this: complR (Set [(5,4), (3,3)]) (Set [(1,3)]). –  Jun 30 '14 at 21:25
  • 2
    @user3791741 Well done for making a question with all the relevant details included now. Have an upvote and a couple of answers! – AndrewC Jun 30 '14 at 21:29

2 Answers2

4

The problem here is how you're calling complR. Your definition may not be what you want either. Examine the type of complR carefully:

complR :: Ord a => Set a -> Rel a -> Rel a

Let's substitute in the definition of Rel a = Set (a, a):

complR :: Ord a => Set a -> Set (a, a) -> Set (a, a)

Now, look at how you're calling it:

complR (Set [(4, 5), (3, 3)]) (Set [(1, 3)])

You're saying that the first argument has type Num b => Set (b, b), which means that a ~ Num b =>(b, b), which means that the second argument must have the type Num b => Set ((b, b), (b, b)). Since you've typed in Set [(1, 3)] for this argument, it attempts to unify the types Num b => b and Num b => (b, b), which results in the error you see above.

How do you fix this? Your options are to either change the definition of complR such that it has the type

complR :: Ord a => Rel a -> Rel a -> Rel a

Or fix how you're calling it as

complR (Set [3, 4, 5]) (Set [(1, 3)])

I'm not going to tell you which is correct in this situation, you'll have to determine that yourself.


A methodology to solve this sort of error is to add some explicit type annotations into your code:

complR (Set [(5, 4), (3, 3)] :: Set (Int, Int)) (Set [(1, 3)] :: Rel Int)

would have thrown the error (in GHC)

Couldn't match type `Int' with `(Int, Int)'
Expected type: Rel (Int, Int)
  Actual type: Rel Int
In the second argument of `complR', namely
  `(Set [(1, 3)] :: Rel Int)'
In the expression:
  complR
    (Set [(5, 4), (3, 3)] :: Set (Int, Int)) (Set [(1, 3)] :: Rel Int)
In an equation for `it':
    it
      = complR
          (Set [(5, 4), (3, 3)] :: Set (Int, Int)) (Set [(1, 3)] :: Rel Int)

Which says more explicitly "Couldn't match type Int with (Int, Int)", which is a more clear indication of what the problem was, you're trying to use a tuple where you need a single number. It even says "Expected type: Rel (Int, Int) ... In the second argument of complR", which tells you something is up.


As a side note, I would highly recommend dropping Hugs in favor of GHC. You'll get much more informative error messages, and a lot more features. Hugs hasn't had development since 2006, while GHC is still actively developed and has new releases regularly. Hugs also has some bugs that tend to crop up from time to time, since it hasn't had any maintenance in 8 years, so you'll be a lot better off grabbing the Haskell Platform, which includes GHC and many popular libraries.

bheklilr
  • 53,530
  • 6
  • 107
  • 163
  • Your answer is better than mine in every regard, except I disagree that ghc should be used by beginners over hugs. Hugs is normally _much_ better at giving you type mismatch errors instead of "No instance for..." errors when that's the problem, and this is a surprising example of it failing to spot the arguments were incorrect rather than a typeclass is missing. You probably don't need to go beyond Haskell 98 when you're just starting out (a stable base for teaching and textbooks was one of the design goals of Haskell 98). – AndrewC Jun 30 '14 at 21:34
  • Thank you very much! Really helpful! I appreciate your answer and the others. It is clear now and it actually also makes sense for me now! Like I said in the comment below, I'm really thankful people are helping with Haskell here. I was afraid I wouldn't get any reply. Thank you again! –  Jun 30 '14 at 21:37
  • @AndrewC I agree that Hugs has a bit more user friendly error messages, but when a newcomer suddenly discovers that they _need_ features only available in Haskell2010, they now have to change their tool chain and get used to these now more complex error messages. In my opinion, it's better to start out with the harder (but more informative) error messages so that you become more familiar with them sooner rather than later. – bheklilr Jun 30 '14 at 21:37
  • 2
    @user3791741 I would actually say we have a pretty vibrant community on the Haskell tag. You'll even run into big names here, like Don Stewart who authored [Real World Haskell](http://book.realworldhaskell.org/), it's not uncommon to see him answer questions about his book. There's plenty of other people active on here who are big in the Haskell community as a whole, so you can usually get really good quality answers. – bheklilr Jun 30 '14 at 21:46
  • Generally maybe, but "Missing instance for..." is a misdiagnosis 99% of the time. A better error message for missing instances could contain: "__Type mismatch.__ `(5,4) :: (Num a,Num b) => (a,b)` does not match the type of `3 :: Num c => c`. __Possible fixes: 1.__ Check you have supplied the right arguments with the right types in the right order to `complR :: Ord a => Set a -> Rel a -> Rel a`. __2.__ Check whether you need an instance for Num (a,b)." I'd happily leave the absent instance message out. After all, if you get a type mismatch between `Num a => a` and `Complex`, it's clear. – AndrewC Jun 30 '14 at 21:52
  • Hugs is also very fast and simple to install. I risk becoming embroiled in an irrelevant debate, and I'd like to emphasise the extent to which you made a very helpful answer and de-emphasise my disagreement with a tiny part of it. I feel good about the OP learning some SO and some FP today! – AndrewC Jun 30 '14 at 21:59
  • @AndrewC I will admit that when I see "Missing instance for ..." I assume I've got my arguments wrong, not that I'm missing an instance of that typeclass. But my point is that getting used to one compiler, then a year later having to switch to a different one with entirely different error messages, conventions, and capabilities has a large cognitive load for someone still relatively new to the Haskell ecosystem. I agree that this argument is fairly irrelevant, and that we should just agree that we each have our preferences, the real point is OP having gotten the help he needed =) – bheklilr Jun 30 '14 at 22:00
2

You have type Rel a = Set (a,a) and the type signature for complR is

complR :: Ord a => Set a -> Rel a -> Rel a

so we should give it a set of a, a set of pairs of as, and it'll give us a new set of pairs.

You tried

complR (Set [(5,4), (3,3)]) (Set [(4,5)])

which is really a type mismatch, because both are relations where the first one should just be a set, but the compiler has kindly (!) tried to go away and figure out if you can make some weird Num instance that would make all the types add up, but it couldn't.

AndrewC
  • 32,300
  • 7
  • 79
  • 115
  • I really appreciate your answer. I unfortunately can not accept two answers (the green button). I have chosen the comment above you. But please know that your comments were also very helpful and I'm very thankful that there are people that are doing this! Keep up the good work. –  Jun 30 '14 at 21:36
  • @user3791741 Don't worry about it. I'd choose bheklilr's answer over mine too! – AndrewC Jun 30 '14 at 21:53