ye9ane
ye9ane

Reputation: 2009

Haskell couldn't match expected type, Weird behaviour

I have a module which looks like this:

module Network where
import Prelude hiding ((==))
import Sort
import Message

data Pair = Conn Loc Loc | Disconn Loc Loc deriving(Show,Eq)
data NC = EmpNC | Inn Pair NC 

instance Eq NC where
EmpNC == EmpNC = True
(Inn p nc1) == nc2 = (nc_include p nc2) && (nc1 == nc2)
_ == _ = False

nc_include::Pair->NC->Bool
nc_include p EmpNC = False
nc_include p1 (Inn p2 nc) = (p1 == p2) || (nc_include p1 nc)

The weird part is that I get couldn't match expected type NC with actual type Pair error for the last line where I say (p1 == p2). Meaning that p1 should be NC rather than Pair. I'm out of idea,can you help? [Edit] The hiding (==) form prelude thing is because I was getting amibiguity error wherever I had "==" operator. I would appreciate if you also suggest a better solution for that as well :D

Upvotes: 0

Views: 265

Answers (1)

firefrorefiddle
firefrorefiddle

Reputation: 3805

First, here is a working version:

module Network where

data Loc = Loc deriving (Show, Eq)
data Pair = Conn Loc Loc | Disconn Loc Loc deriving(Show,Eq)
data NC = EmpNC | Inn Pair NC 

instance Eq NC where
   EmpNC       == EmpNC = True
   (Inn p nc1) == nc2   = (nc_include p nc2) && (nc1 == nc2)
   _           == _     = False

nc_include :: Pair -> NC-> Bool
nc_include p  EmpNC = False
nc_include p1 (Inn p2 nc) = (p1 == p2) || (nc_include p1 nc)

What's the difference (besides my arbitrarily defining Loc)? Mainly formatting.

I suppose what happened is this:

You tried to write an instance of Eq for NC:

instance Eq NC where
EmpNC == EmpNC = True
...

and realized the compiler didn't like this, saying it conflicted with (==) from the Prelude. However, you drew the wrong conclusions from this, hiding Prelude.(==) and going on. Now the compiler didn't complain, but it parsed what you did like this:

instance Eq NC where -- make NC an instance of Eq with only default definitions

EmpNC == EmpNC = True -- define a new function (==) of type (NC -> NC -> Bool)
...

That's why now you can't apply (==) to Pairs, because it's type is (NC -> NC -> Bool), hence the compiler tells you that it would have expected an NC instead of a Pair.

Now, the core of the matter is that instance definitions follow whitespace formatting rules, so you must leave at least one whitespace column before the functions in your instance definition:

instance Eq NC where 
 EmpNC == ...

works, while

instance Eq NC where 
EmpNC == ...

doesn't.

The same is true for some other things like class, do, case etc.

Upvotes: 12

Related Questions