Ambiguous occurrence '==' - haskell

I'm just learning Haskell and still trying to figure out how things work.
So I'm creating a list class that can hold a mixture of Int and Char.
data Algebra = Empty
| Nmbr Int Algebra
| Smbl Char Algebra
Then I try to make it an instance of Eq
instance Eq Algebra where
Empty == Empty = True
(Nmbr x xl) == (Nmbr y yl) = (x == y) && (xl==yl)
(Smbl x xl) == (Smbl y yl) = (x == y) && (xl==yl)
_ == _ = False
and I get an Ambiguous occurrence == compile error. It can't tell the difference between Main.== and Prelude.==. If I manually replace all == with Main.== or Prelude.== then it compiles fine.
I don't see why the compiler is having so much difficulty here. x and y are clearly defined as being Int or Char in each case. I've compared what I am doing to the numerous tutorial examples (eg http://www.haskell.org/tutorial/classes.html) and I can't determine why the compiler is being such a jerk in this situation :P

You need to indent the body of your instance definition:
instance Eq Algebra where
Empty == Empty = True
(Nmbr x xl) == (Nmbr y yl) = (x == y) && (xl==yl)
(Smbl x xl) == (Smbl y yl) = (x == y) && (xl==yl)
_ == _ = False
Otherwise the compiler sees it as two things:
An instance Eq Algebra with an empty body, producing the default definitions of a == b = not (a /= b) and vice versa.
A definition of a new infix operator named ==.
Then using == in your code now produces an ambiguity between the == from Eq (defined in Prelude) and the == in your code (Main).
And yes, deriving Eq gives you exactly this kind of structural equality.

Related

How can I return the primitive data type from polymorphism?

Given some custom sum data type,
data Type = Thing Char | NotThing Char
How can I use == to compare between the Char here and some other Char? As below:
let f = 'a'
NotThing e == f
>>> True
Of course, this code cannot compare between types as NotThing is a separate type to Char.
If x :: Char and y :: Type, then the following expressions (among others) are well-typed:
y == Thing x
y == NotThing x
y `elem` [Thing x, NotThing x]
case y of { Thing x' -> x == x'; NotThing x' -> x == x' }
Probably the last one is closest to what you want. I would abstract slightly and write
extract :: Type -> Char
extract (Thing x') = x'
extract (NotThing x') = x'
because I would expect that to occasionally be useful in other contexts. With that in hand, the following expression is also well-typed:
extract y == x
Of course, you'll want to pick a better name than extract, just like you'll do for Type, Thing, and NotThing.

How to check if coords(x,y) are valid on a board in Haskell

I have a function
isValid :: CoOrd -> Bool
Where CoOrd is a tuple pair (x,y)
The boards size is ['a'..'h'] ['1'..'8'] so I want to check if the given CoOrds are valid for this board (CoOrds x < ['a'..'h'], CoOrds y ['1'..'8'])
I'm fine with the logic of this question, its just the syntax as I'm new to haskell, so I'm looking for something like this
if (CoOrd(x _) == ['a'..'h'])
if (CoOrd(_ y) == ['1'..'8'])
return True
else return False
The basic approach is to use direct comparisons:
isValid :: CoOrd -> Bool
isValid (x,y) = x >= 'a' && x <= 'h' && y >= '1' && y <= '8'
A more advanced alternative is to exploit Data.Ix.inRange:
import Data.Ix
isValid :: CoOrd -> Bool
isValid = inRange (('a','1'),('h','8'))
You can also use elem, as others pointed out, but elem will scan the whole list and perform pointwise comparisons (8+8 comparisons, in the worst case), while the methods above will only do four comparisons.
Finally, a few comments on your original code:
Don't use return in Haskell unless you are writing monadic code
Don't use if condition then True else False -- that's noise, and it is equivalent to conditions. Consider using boolean operators instead, which is often simpler.
Why not make some new types for your X and Y coordinates so the type checker gives you a static guarantee that any CoOrd value is correct?
For example, I think you have type CoOrd = (Char,Int). Instead try:
data XCo = A | B | C | D | E | F | G | H deriving (Eq,Ord,Show,Enum)
data YCo = Y1 | Y2 | Y3 | Y4 | Y5 | Y6 | Y7 | Y8 deriving (Eq,Ord,Enum)
instance Show YCo where
show y = show (fromEnum y + 1)
type CoOrd = (XCo,YCo)
And now anywhere you were using character literals like 'a', 'b' etc you use A, B etc. Same with the numbers and the Y axis - 1 becomes Y1 etc.
isValid (x,y) = x `elem` ['a'..'h'] && y `elem` ['1'..'8']
In addition to the other answers instead of using tuples you may define a new type, for example ChessBoard.
Since you are in need of checking the validity of the entered position it might be wise to make it Maybe ChessBoard type as well.
Accordingly you may come up with something like
module ChessBoard (ChessBoard, chessBoard) where
data ChessBoard = CB Char Int deriving (Eq, Ord, Show)
chessBoard :: Char -> Int -> Maybe ChessBoard
chessBoard c n | elem c ['a'..'h'] && elem n [1..8] = Just (CB c n)
| otherwise = Nothing
Here as you may notice we are not exporting the data constructor CB Char Int so the only way to create your chess board position data is through the chessBoard function and there will be no illegal board positions.
I mean;
*Main> chessBoard 'a' 3
Just (CB 'a' 3)
*Main> chessBoard 'h' 9
Nothing
*Main> let pos = Just (CB 'a' 11) -- trying to assign an illegal position directly
<interactive>:259:17: error:
Data constructor not in scope: CB :: Char -> Integer -> a

why is this function non exhaustive?

Compiler warns the function "insert" is non-exhaustive in the following code:
data Set a = Empty | Set a (Set a) (Set a) deriving (Eq, Show)
insert :: (Ord a) => a -> Set a -> Set a
insert x Empty = Set x Empty Empty
insert x (Set v l r)
| x <= v = Set v (insert x l) r
| v < x = Set v l (insert x r)
-- | otherwise = Set x Empty Empty
main :: IO ()
main = do
let x = insert (5::Int) Empty
print x
GHC reports this
test.hs:4:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘insert’: Patterns not matched: _ (Set _ _ _)
If I uncomment the last line (it's commented out now) in the function, GHC does not report any warning. So I guess GHC thinks the guards are non-exhaustive. But why? If x and v are instances of Ord, then I guess
(x <= v) and (v < x) are all the possible outcomes of comparison?
What if I define this instance:
newtype Fuzzy = Fuzzy Double
instance Eq Fuzzy where
Fuzzy a == Fuzzy b = abs (a-b) < 0.1
instance Ord Fuzzy where
Fuzzy a < Fuzzy b = a < b-0.1
Fuzzy a <= Fuzzy b = a <= b
Then for e.g. v = Fuzzy 0, x = Fuzzy 0.1, you have (x <= v) = (0.1 <= 0) which is false, but (v < x) = (0 < 0) which is also false. Hence both of your guards will fail.
This isn't so hypothetical, in fact Double itself already has such behaviour in degenerate values:
Prelude> sqrt (-1) < 0
False
Prelude> 0 <= sqrt (-1)
False
Now, it's very debatable whether these are really good, even well-formed Ord instances, but at any rate the compiler can't guarantee something like that won't happen. Hence it also can't make the assumption that not (x <= v) implies v < x, so what should happen if neither is fulfilled?
The usual thing to do if you assume all Ord instances you received are docile is to just make the second clause already catch-all:
insert x (Set v l r)
| x <= v = Set v (insert x l) r
| otherwise = Set v l (insert x r)
However, depending on your philosophy, your original code might actually be better. With the catch-all in the second, you just defer the weirdness if someone hands you NaN values. This makes it all the more difficult to understand what's going on.
If tend to deliberately not complete patterns with “impossible cases” in experimental code: this way I'll at least always get a clear runtime error telling me at which point in the code things go awry. Once the code essentially works and you want to make it production-ready, you can then toss in -Wall and learn about all spots where you'd better add some explicit handling of pathological behaviour like the one I mentioned.

any working operator overloading example in haskell

I want to overload any operator . i want to do such a simple function that for instance think about overloading of == operator .Overload == such that
x==y
returns x .
Or x==y return x+y. It doesn't matter what . Can you show me any simple operator overloading example? I cannot find any example on the web unfortunately.
For example;when i call Tree a == Tree a
return 5 (it always return 5. I select it ,it is not related to any thing)
or when i call 3==4
return : 7
I tried the below codes(i find it from haskell.org) but it cannot compile.
class Eq a where
(==) ::a -> a -> Int
instance Eq Integer where
x == y = 5
instance Eq Float where
x == y = 5
Neither the below code works:
data Tree a = Node a | Empty
class Tree a where
(==) :: Tree a -> Tree a -> Int
instance Tree Integer where
x == y = 1
I take the error :
Ambiguous occurrence `Eq'
It could refer to either `Main.Eq', defined at Operations.hs:4:7
or `Prelude.Eq',
imported from `Prelude' at Operations.hs:1:1
(and originally defined in `GHC.Classes')
You can't hide instances from an imported module. See for example: Explicitly import instances
It looks like the "overloading" you're trying to do is to allow (==) for other types, like trees. This is easy! Just simply create a new instance:
data Tree a = Leaf a | Branch [Tree a]
instance (Eq a) => Eq (Tree a) where
(Leaf a) == (Leaf b) = a == b
(Branch a) == (Branch b) = a == b
_ == _ = False
(You could also just derive the Eq instance)
Try hiding the == from the Prelude first. You only need a type class if you want it to work differently for different types.
import Prelude hiding ((==))
x == y = x
Here's a +++ operator that acts like the (++) operator used to append lists:
(+++) :: [a]->[a]->[a]
x +++ [] = x
[] +++ x = x
x +++ y = (init x) +++ ((last x) : y)

Custom Ord instance hangs on lists

import Data.Function (on)
import Data.List (sort)
data Monomial = Monomial
{ m_coeff :: Coefficient
, m_powers :: [(Variable, Power)]
}
deriving ()
instance Ord Monomial where
(>=) = on (>=) m_powers
instance Eq Monomial where
(==) = on (==) m_powers
That's an excerpt from my code, cut down to principal size. Let's try comparing:
*Main> (Monomial 1 [("x",2)]) > (Monomial (-1) [])
/* Computation hangs here */
*Main> (Monomial 1 [("x",2)]) < (Monomial (-1) [])
/* Computation hangs here */
On a side note, it's interesting that if I replace s/(>=)/(>)/g in instance declaration, it will not hang on the fist pair, but still will on the second:
*Main> (Monomial 1 [("x",2)]) > (Monomial (-1) [])
True
*Main> (Monomial 1 [("x",2)]) < (Monomial (-1) [])
/* Computation hangs here */
Although the standard states minimal declaration of Eq instance to be either$compare$ or $(>=)$.
What might be the problem here? (>=) on lists seems to work just fine.
Short answer:
You need to provide either (<=) or compare to have a complete definition for Ord, not (>=).
Longer explanation:
It is common for type classes in Haskell to have default implementations of some methods implemented in terms of other methods. You can then choose which ones you want to implement. For example, Eq looks like this:
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
x == y = not (x /= y)
Here, you must either implement (==) or (/=), otherwise trying to use either of them will cause an infinite loop. Which methods you need to provide is usually listed as the minimal complete definition in the documentation.
The minimal complete definition for Ord instances, as listed in the documentation, is either (<=) or compare. Since you've only provided (>=), you have not provided a complete definition, and therefore some of the methods will loop. You can fix it by e.g. changing your instance to provide compare instead.
instance Ord Monomial where
compare = compare `on` m_powers
Let's look at the default instance for Ord:
class (Eq a) => Ord a where
compare :: a -> a -> Ordering
(<), (<=), (>), (>=) :: a -> a -> Bool
max, min :: a -> a -> a
compare x y = if x == y then EQ
-- NB: must be '<=' not '<' to validate the
-- above claim about the minimal things that
-- can be defined for an instance of Ord:
else if x <= y then LT
else GT
x < y = case compare x y of { LT -> True; _ -> False }
x <= y = case compare x y of { GT -> False; _ -> True }
x > y = case compare x y of { GT -> True; _ -> False }
x >= y = case compare x y of { LT -> False; _ -> True }
-- These two default methods use '<=' rather than 'compare'
-- because the latter is often more expensive
max x y = if x <= y then y else x
min x y = if x <= y then x else y
So, if you supply >= and == as above, only, then you are in trouble, since:
> is defined in terms of compare
But
compare is defined in terms of <=
<= is defined in terms of compare
So you have an infinite loop!
A minimum definition must defined <= or compare, not '>=`.

Resources