Haskell 中的函数相等,语法问题
Equality of functions in Haskell, syntax problems
我一直在尝试为一个函数实现一个实例 Eq,但我不断收到语法错误,而且找不到任何地方应该是怎样的。如果一个函数对于每个输入都抛出相同的输出,则该函数是相等的。所以我试着检查每个输入并检查结果是否相等。
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
错误与 Fkt
数据构造函数的使用有关:您的 Fkt
数据构造函数只有 一个 属性:函数 f
将 Zahlraum_0_10
映射到 Zahlraum_0_10
。因此,您使用 Fkt f1
从 Fkt
中解压缩函数,因此没有 _
作为第二个属性:
使用 all :: Foldable f => (a -> Bool) -> f a -> Bool
可能会更好,因为这样可以减少比较这两个函数的代码量(并且更不容易出错):
instance Eq Funktion where
<strong>Fkt f1</strong> == <strong>Fkt f2</strong> = all go [N, I, II, III, IV, V, VI, VII, VIII, IX, X, F]
where go x = f1 x == f2 x
我们也可以使用 liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
而不是定义 go
函数:
import Control.Applicative(<strong>liftA2</strong>)
instance Eq Funktion where
Fkt f1 == Fkt f2 = all <strong>(liftA2 (==) f1 f2)</strong> [N, I, II, III, IV, V, VI, VII, VIII, IX, X, F]
我们不必显式定义值列表:因为所有数据构造函数都没有参数,所以可以很容易地使它们成为 Enum
和 Bounded
:[=29= 的实例]
data Zahlraum_0_10 = N | I | II | III | IV | V | VI
| VII | VIII | IX | X | F deriving (<strong>Bounded</strong>, <strong>Enum</strong>, Eq, Ord, Show)
在这种情况下,我们可以确定两个函数是否映射到每个参数的相同值:
import Control.Applicative(liftA2)
instance Eq Funktion where
Fkt f1 == Fkt f2 = all (liftA2 (==) f1 f2) <strong>[minBound ..]</strong>
我一直在尝试为一个函数实现一个实例 Eq,但我不断收到语法错误,而且找不到任何地方应该是怎样的。如果一个函数对于每个输入都抛出相同的输出,则该函数是相等的。所以我试着检查每个输入并检查结果是否相等。
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
错误与 Fkt
数据构造函数的使用有关:您的 Fkt
数据构造函数只有 一个 属性:函数 f
将 Zahlraum_0_10
映射到 Zahlraum_0_10
。因此,您使用 Fkt f1
从 Fkt
中解压缩函数,因此没有 _
作为第二个属性:
使用 all :: Foldable f => (a -> Bool) -> f a -> Bool
可能会更好,因为这样可以减少比较这两个函数的代码量(并且更不容易出错):
instance Eq Funktion where
<strong>Fkt f1</strong> == <strong>Fkt f2</strong> = all go [N, I, II, III, IV, V, VI, VII, VIII, IX, X, F]
where go x = f1 x == f2 x
我们也可以使用 liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c
而不是定义 go
函数:
import Control.Applicative(<strong>liftA2</strong>)
instance Eq Funktion where
Fkt f1 == Fkt f2 = all <strong>(liftA2 (==) f1 f2)</strong> [N, I, II, III, IV, V, VI, VII, VIII, IX, X, F]
我们不必显式定义值列表:因为所有数据构造函数都没有参数,所以可以很容易地使它们成为 Enum
和 Bounded
:[=29= 的实例]
data Zahlraum_0_10 = N | I | II | III | IV | V | VI
| VII | VIII | IX | X | F deriving (<strong>Bounded</strong>, <strong>Enum</strong>, Eq, Ord, Show)
在这种情况下,我们可以确定两个函数是否映射到每个参数的相同值:
import Control.Applicative(liftA2)
instance Eq Funktion where
Fkt f1 == Fkt f2 = all (liftA2 (==) f1 f2) <strong>[minBound ..]</strong>