Years ago I read about how Haskell compares boolean expressions and I wanted to see if I can use the same concept in my project (F#), but I don't understand how it works:
Source: https://hackage.haskell.org/package/ghc-prim-0.10.0/docs/src/GHC.Classes.html#%3D%3D
x /= y = not (x == y)
x == y = not (x /= y)
It makes perfect sense, but how doesn't it end in a never-ending recursion?
Context: in my project I have spent and unspent coins and I think they could be handled similar to booleans, where a coin is unspent when it is not spent and it is spent when it is not unspent.
It makes perfect sense, but how doesn't it end in a never-ending recursion?
This is a typeclass, the instances should make an implementation. What you see is a default (fallback) implementation.
The compiler will normally enforce this, indeed. The class does not only provide function signatures, and default implementations, but shows:
class Eq a where
-- …
{-# MINIMAL (==) | (/=) #-}
the minimal means that the instances of the typeclass will either have to implement (==)
or (/=)
(they can of course implement both).
This is also the case for any sensical instance of Eq
, indeed, for example with Int
:
instance Eq Int where (==) = eqInt (/=) = neInt
where eqInt
and neInt
in this case are implemented as:
eqInt, neInt :: Int -> Int -> Bool (I# x) `eqInt` (I# y) = isTrue# (x ==# y) (I# x) `neInt` (I# y) = isTrue# (x /=# y)
These then have ==#
functions that work on unboxed Int#
values.
Beware that a class in Haskell is a typeclass, this looks more like what one would see as an interface in object-oriented programming. It does not deal with (concrete) data, it just provides an interface that should be implemented.