I've been trying to implement an instance Eq for a Function but I keep getting Syntax erros and can't find anywhere how it's supposed to be. A function is equal if for every input it throws the same output. So I tried just going through every input and check if the results are equal.
newtype Funktion = Fkt { f :: Zahlraum_0_10 -> Zahlraum_0_10 }
data Zahlraum_0_10 = N | I | II | III | IV | V | VI
| VII | VIII | IX | X | F deriving (Eq,Ord,Show)
instance Eq Funktion where
(==) (Fkt f2 _) (Fkt f1 _) = f2 I == f1 I && f2 II == f1 II && f2 III == f1 III &&
f2 IV == f1 IV && f2 V == f1 V && f2 VI == f1 VI && f2 VII == f1 VII && f2 VIII == f1 VIII &&
f2 IX == f1 IX && f2 X == f1 X && f2 N == f1 N && f2 F == f1 F
CodePudding user response:
The error is about the use of the Fkt
data constructor: your Fkt
data constructor has only one attribute: the function f
that maps a Zahlraum_0_10
to a Zahlraum_0_10
. You thus unpack the function out of the Fkt
with Fkt f1
, so without a _
as second attribute:
It might also be better to work with all :: Foldable f => (a -> Bool) -> f a -> Bool
since this reduce the amount of code (and makes it less error prone) to compare the two functions:
instance Eq Funktion where
Fkt f1 == Fkt f2 = all go [N, I, II, III, IV, V, VI, VII, VIII, IX, X, F]
where go x = f1 x == f2 x
We can also work with liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
instead of defining a go
function:
import Control.Applicative(liftA2)
instance Eq Funktion where
Fkt f1 == Fkt f2 = all (liftA2 (==) f1 f2) [N, I, II, III, IV, V, VI, VII, VIII, IX, X, F]
We do not have to define the list of values explicitly: since all the data constructors have no parameters, one can easily make these an instance of Enum
and Bounded
:
data Zahlraum_0_10 = N | I | II | III | IV | V | VI
| VII | VIII | IX | X | F deriving (Bounded, Enum, Eq, Ord, Show)
In that case we can determine if the two functions map to the same value for each parameter with:
import Control.Applicative(liftA2)
instance Eq Funktion where
Fkt f1 == Fkt f2 = all (liftA2 (==) f1 f2) [minBound ..]