Can't resolve class dependences (making Boolean class)

Hello! I'm trying to have a class for booleans called Boolean (the methods are not complete): class MyEq a where (===) :: (Boolean b) => a -> a -> b class (MyEq a) => Boolean a where (/\) :: a -> a -> a instance MyEq Bool where x === y = x==y instance Boolean Bool where (/\) = (&&) However, to make Bool an instance of Boolean I need to make it an instance of MyEq first, which I can't, because to define === I need Bool to be in Boolean. Indeed the code above give the error: Could not deduce (b ~ Bool) from the context (Boolean b) bound by the type signature for === :: Boolean b => Bool -> Bool -> b at 1.hs:8:5-18 `b' is a rigid type variable bound by the type signature for === :: Boolean b => Bool -> Bool -> b at 1.hs:8:5 In the expression: x == y In an equation for `===': x === y = x == y In the instance declaration for `MyEq Bool' Failed, modules loaded: none. How can I overcome the issue?

On 13 September 2011 23:04, Grigory Sarnitskiy
Hello! I'm trying to have a class for booleans called Boolean (the methods are not complete):
class MyEq a where (===) :: (Boolean b) => a -> a -> b
This means that === potentially returns _any_ instance of Boolean. Let's say for example that I define "data MyBool = T | F" and make it an instance of MyEq and Boolean. That means that T === F must be able to return either a Bool, MyBool or any other instance of Boolean that the _caller_ chooses. If this is what you want, then I suggest that you do something like: class (MyEq a) => Boolean a where (/\) :: a -> a -> a fromBool :: Bool -> a Then the instance becomes: instance MyEq Bool where x === y = fromBool $ x==y instance Boolean Bool where (/\) = (&&) fromBool = id -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

The problem is that an implementation of (===) must return a result of type b for *any* type b which is an instance of Boolean. For example, if I made data X = A | B instance Boolean X where ... then I would be able to have: eqX :: MyEq a => a -> a -> X eqX = (===) That's all fine and probably the reason why you are going through these hoops. However, look at your definition for MyEq Bool: a === b = a == b Now, "a == b" has type Bool. What would happen if I wanted an X instead? You would need something like class Boolean a where (/\) :: a -> a -> a fromBool :: Bool -> a Your instance would then become instance MyEq Bool where a === b = fromBool (a == b) You may want to take a look at the Awesome Prelude [1], which implement this and much more. Cheers! =) [1] https://github.com/tomlokhorst/AwesomePrelude -- Felipe.
participants (3)
-
Felipe Almeida Lessa
-
Grigory Sarnitskiy
-
Ivan Lazar Miljenovic