Haskell Eq definition realizing a result - haskell

I was reading the definition for the Eq typeclass in the Data library, and I'm confused. At what point is it realized that two values are equal or not equal. From what I see, it looks like they would just call each other ad infinitum.
It's defined as so:
class Eq a where
(==), (/=) :: a -> a -> Bool
x /= y = not (x == y)
x == y = not (x /= y)
Would somebody mind explaining where it realizes the Bool value? Are they even calling each other, or is something else going on?

That’s the default implementation of those methods, and yes, it is circular. If you use them as-is, you’ll loop:
data Foo = Foo
instance Eq Foo
> Foo == Foo
^CInterrupted
The circular definitions exist so you can implement (==) and get (/=) for free, or vice versa:
data Foo = Foo
instance Eq Foo where
x == y = True
> Foo /= Foo
False
See also the Ord class, which explains what the minimal complete definition is in that particular case.

Related

How do you apply function constraints in instance methods in Haskell?

I'm learning how to use typeclasses in Haskell.
Consider the following implementation of a typeclass T with a type constrained class function f.
class T t where
f :: (Eq u) => t -> u
data T_Impl = T_Impl_Bool Bool | T_Impl_Int Int | T_Impl_Float Float
instance T T_Impl where
f (T_Impl_Bool x) = x
f (T_Impl_Int x) = x
f (T_Impl_Float x) = x
When I load this into GHCI 7.10.2, I get the following error:
Couldn't match expected type ‘u’ with actual type ‘Float’
‘u’ is a rigid type variable bound by
the type signature for f :: Eq u => T_Impl -> u
at generics.hs:6:5
Relevant bindings include
f :: T_Impl -> u (bound at generics.hs:6:5)
In the expression: x
In an equation for ‘f’: f (T_Impl_Float x) = x
What am I doing/understanding wrong? It seems reasonable to me that one would want to specialize a typeclass in an instance by providing an accompaning data constructor and function implementation. The part
Couldn't match expected type 'u' with actual type 'Float'
is especially confusing. Why does u not match Float if u only has the constraint that it must qualify as an Eq type (Floats do that afaik)?
The signature
f :: (Eq u) => t -> u
means that the caller can pick t and u as wanted, with the only burden of ensuring that u is of class Eq (and t of class T -- in class methods there's an implicit T t constraint).
It does not mean that the implementation can choose any u.
So, the caller can use f in any of these ways: (with t in class T)
f :: t -> Bool
f :: t -> Char
f :: t -> Int
...
The compiler is complaining that your implementation is not general enough to cover all these cases.
Couldn't match expected type ‘u’ with actual type ‘Float’
means "You gave me a Float, but you must provide a value of the general type u (where u will be chosen by the caller)"
Chi has already pointed out why your code doesn't compile. But it's not even that typeclasses are the problem; indeed, your example has only one instance, so it might just as well be a normal function rather than a class.
Fundamentally, the problem is that you're trying to do something like
foobar :: Show x => Either Int Bool -> x
foobar (Left x) = x
foobar (Right x) = x
This won't work. It tries to make foobar return a different type depending on the value you feed it at run-time. But in Haskell, all types must be 100% determined at compile-time. So this cannot work.
There are several things you can do, however.
First of all, you can do this:
foo :: Either Int Bool -> String
foo (Left x) = show x
foo (Right x) = show x
In other words, rather than return something showable, actually show it. That means the result type is always String. It means that which version of show gets called will vary at run-time, but that's fine. Code paths can vary at run-time, it's types which cannot.
Another thing you can do is this:
toInt :: Either Int Bool -> Maybe Int
toInt (Left x) = Just x
toInt (Right x) = Nothing
toBool :: Either Int Bool -> Maybe Bool
toBool (Left x) = Nothing
toBool (Right x) = Just x
Again, that works perfectly fine.
There are other things you can do; without knowing why you want this, it's difficult to suggest others.
As a side note, you want to stop thinking about this like it's object oriented programming. It isn't. It requires a new way of thinking. In particular, don't reach for a typeclass unless you really need one. (I realise this particular example may just be a learning exercise to learn about typeclasses of course...)
It's possible to do this:
class Eq u => T t u | t -> u where
f :: t -> u
You need FlexibleContextx+FunctionalDepencencies and MultiParamTypeClasses+FlexibleInstances on call-site. Or to eliminate class and to use data types instead like Gabriel shows here

Haskell Eq between different types

I need to use this data structure data D = C Int Float and I need to compare it with an Int, for example a::D == 2.
How can I create an instance to define this kind of Eq ?
Thank you!
I would implement a projection:
getInt :: D -> Int
getInt (C i _) = i
and then compare with it:
getInt myD == 5
you can even include this into a record:
data D = C { getInt :: Int, getFloat :: Float }
if you like
You can't; == has signature a -> a -> Bool, so it can't be used like this.
Using the convertible package you can define
(~==) :: (Convertible a b, Eq b) => a -> b -> Bool
x ~== y = case safeConvert x of
Right x' -> x' == y
Left _ -> False
(==~) :: (Convertible b a, Eq a) => a -> b -> Bool
(==~) = flip (~==)
instance Convertible Int D where ...
-- or D Int depending on what you have in mind
Without depending on convertible, you could just define a conversion function either from Int to D (and write a == fromInt 2) or vice versa.
A less recommended route (for this specific case I think it's simply worse than the first solution) would be to define your own type class, e.g.
class Eq' a b where
(=~=) :: a -> b -> Bool
instance Eq a => Eq' a a where
x =~= y = x == y
instance Eq' D Int where ...
etc.
This can be done, but I doubt you will want to do this. As Alexey mentioned the type of (==) is Eq a=>a->a->Bool, so the only way to make this work would be to make 2 have type D. This may seem absurd at first, but in fact numbers can be made to have any type you want, as long as that type is an instance of Num
instance Num D where
fromInteger x = C x 1.0
There are still many things to work out, though....
First, you need to fully implement all the functions in Num, including (+), (*), abs, signum, fromInteger, and (negate | (-)).
Ugh!
Second, you have that extra Float to fill in in fromInteger. I chose the value 1.0 above, but that was arbitrary.
Third, you need to actually make D an instance of Eq also, to fill in the actual (==).
instance Eq D where
(C x _) == (C y _) = x == y
Note that this is also pretty arbitrary, as I needed to ignore the Float values to get (==) to do what you want it to.
Bottom line is, this would do what you want it to do, but at the cost of abusing the Num type, and the Eq type pretty badly.... The Num type should be reserved for things that you actually would think of as a number, and the Eq type should be reserved for a comparison of two full objects, each part included.

Is an infinitely recursive type useful?

Lately I've been experimenting with the general question, what will GHC allow me to do? I was surprised to find, that it considers the following program as valid
module BrokenRecursiveType where
data FooType = Foo FooType
main = print "it compiles!"
At first I thought, how is this useful? Then I remembered that Haskell is lazy, so I could, perhaps, define a function like the following to use it
allTheFoos = Foo allTheFoos
Then I thought, so how is this useful?
Are there any valuable use cases (thought up or actually experienced) for types of similar form to FooType?
An evaluation counter
You could, hypothetically, use FooType to optionally abort a recursive function early: For example, take this code:
foo _ 0 = 1
foo (Foo x) n = n * foo x (n-1)
If you call foo allTheFoos, then you get the plain factorial function. But you can pass a different value of type FooType, e.g.
atMostFiveSteps = Foo (Foo (Foo (Foo (Foo (error "out of steps")))))
and then foo atMostFiveSteps will only work for values smaller than 6.
I’m neither saying that this is particularly useful nor that this is the best way to implement such a feature...
A void type
BTW, there is a similar construction, namely
newtype FooType' = Foo' FooType'
which is useful: It is one way to define the void type that has no values besides ⊥. You can still define
allTheFoos' = Foo' allTheFoos'
as before, but because operationally, Foo does nothing, this is equivalent to x = x and hence also ⊥.
Let's just slightly extend your data type - let's wrap the recursion into a type parameters:
data FooType f = Foo (f (FooType f))
(so your original data type would be FooType Identity).
Now we can modulate the recursive reference by any f :: * -> *. But this extended type is extremely useful! In fact, it can be used to express any recursive data type using a non-recursive one. One well kwnown package where it's defined is recursion-schemes, as Fix:
newtype Fix f = Fix (f (Fix f))
For example, if we define
data List' a r = Cons' a r | Nil'
then Fix (List' a) is isomorphic to [a]:
nil :: Fix (List' a)
nil = Fix Nil'
cons :: a -> Fix (List' a) -> Fix (List' a)
cons x xs = Fix (Cons' x xs)
Moreover, Fix allows us to define many generic operations on recursive data types such as folding/unfolding (catamorphisms/anamorphisms).
An extension of your FooType could be an abstract syntax tree. Taking a simple example language only having integers, sums and inverses, the type definition would be
data Exp = AnInt Integer
| AnInverse Exp
| ASum Exp Exp
All the following would be Exp instances:
AnInt 2 -- 2
AnInverse ( AnInt 2 ) -- 1 / 2
AnInverse ( ASum ( AnInt 2 ) ( AnInt 3 ) ) -- 1 / ( 2 + 3 )
AnInverse ( ASum 1 ( AnInverse 2 ) ) -- 1 / ( 1 + 1 / 2 )
If we removed AnInt and ASum from the Exp definition, the type would be isomorphic to your FooType (with AnInverse replacing Foo).
data FooType = Foo FooType
allTheFoos = Foo allTheFoos
I think there are two useful ways to look at this type.
First is the "moral" way—the common approach where we pretend that Haskell types don't have "bottom" (non-terminating) values. From this perspective, FooType is a unit type—a type that has only one value, just like (). This is because if you forbid bottoms, then the only value of type Foo is your allTheFoos.
From the "immoral" perspective (where bottoms are allowed), FooType is either an infinite tower of Foo constructors, or a finite tower of Foo constructors with a bottom at the bottom. This is similar to the "moral" interpretation of this type:
data Nat = Zero | Succ Nat
...but with bottom instead of zero, which means that you can't write functions like this one:
plus :: Nat -> Nat -> Nat
plus Zero y = y
plus (Succ x) y = Succ (x `plus` y)
Where does that leave us? I think the conclusion is that FooType isn't really an useful type, because:
If you look at it "morally" it's equivalent to ().
If you look at it "immorally" it's similar to Nat but any functions that tries to match a "zero" is non-terminating.
The following type:
newtype H a b = Fn {invoke :: H b a -> b}
while not exactly the same as yours but is in a similar spirit, have been shown by Launchbury, Krstic, and Sauerwein to have interesting uses regarding corouitining: https://arxiv.org/pdf/1309.5135.pdf

What is the differences between class and instance declarations?

I am currently reading this, but if I am honest I am struggling to see what
class Eq a where
(==) :: a -> a -> Bool
achieves, which
instance Eq Integer where
x == y = x `integerEq` y
doesnt achieve. I understand the second code defines what the result of performing equality on two Integer types should be. What is the purpose of the first then??
The class declaration says "I'm going to define a bunch of functions now which will work for several different types". The instance declaration says "this is how these functions work for this type".
In your specific example, class Eq says that "Eq means any type that has a function named ==", whereas the instance Eq Integer says "this is how == works for an Integer".
The first defines what operations must be provided for a type to be comparable for equality. You can then use that to write functions that operate on any type that is comparable for equality, not just integers.
allSame :: Eq a => [a] -> Bool
allSame [] = []
allSame (x:xs) = foldr True (==x) xs
This function works for integers because instances for Eq Integer exists. It also works for strings ([Char]) because an instance for Eq Char exists, and an instance for lists of types that have instances of Eq also exists (instance Eq a => Eq [a]).
There is one class and many instances for different types. That's why the class specifies the required signature (interface; classes can also specify default implementations, but that's beside the point), and instance the body (implementation). You then use class name as a constraint that means "any type a that implements Eq operations, i.e. have an instance in Eq".
Read Learn you a Haskell or Real World Haskell, they're better than the haskell.org tutorial.
Let's say you want to implement a generic algorithm or data structure, "generic" meaning polymorphic: it should work for any data type. For example, let's say you want to write a function that determines whether three input values are equal.
Taking a specific (monomorphic) case, you can do this for integers:
eq3 :: Int -> Int -> Int -> Bool
eq3 x y z = x == y && y == z
We'd expect the above definition to work for other types as well, of course, but if we simply tell the compiler that the function should apply to any type:
eq3 :: a -> a -> a -> Bool
eq3 x y z = x == y && y == z
... the compiler complains that the == function doesn't apply to our generic a:
<interactive>:12:49:
No instance for (Eq a)
arising from a use of `=='
In the first argument of `(&&)', namely `x == y'
In the expression: x == y && y == z
In an equation for `eq3': eq3 x y z = x == y && y == z
We have to tell the compiler that our type a is an instance of the Eq type class, which you already noticed is where the == function is declared. See the difference here:
eq3 :: Eq a => a -> a -> a -> Bool
eq3 x y z = x == y && y == z
Now we have a function that can operate uniformly on any type a belonging to the Eq type class.

"maybe"-like function for Bool and List?

Sometimes i find myself progamming the pattern "if the Bool is not false" or "if the list is not empty use it, otherwise use something else".
I am looking for functions for Bool and List that are what the "maybe" function is to Maybe. Are there any?
Update: I meant to use the Bool-case as a generalization of the List-case. For example when working with Data.Text as T:
if T.null x then x else foo x
I am looking to reduce such boiler plate code.
maybe is the catamorphism of the Maybe type.
foldr is the catamorphism of the list type.
Data.Bool.bool is the catamorphism of the Bool type.
If you had used maybe like: maybe x (const y)
You could use: foldr (const (const y)) x
Your example if T.null x then x else foo x could be written with bool as
bool foo id (T.null x) x
(it takes the False case first, the opposite of if)
I think the answer is probably that there isn't such a generic function. As djv says, you can perhaps build on Data.Monoid to write one, something like:
maybe' :: (Eq a, Monoid a) => b -> (a -> b) -> a -> b
maybe' repl f x = if x == mempty then repl else f x
But I don't know of any functions in the standard library like that (or any that could easily be composed together to do so).
Check Data.Monoid, it's a typeclass describing data types which have a designated empty value and you can pattern-match on it to write your generic function. There are instances for Bool with empty value False and for List with empty value [].

Resources