所以我写了这个程序,一切正常;) 我想改善它。我还可以使用/ =编译两个不同的时间集,并得到True。 我有点困惑。
data Time = Localtime {hour, minute :: Int}
| Globaltime {hour, minute, difference :: Int}
| LocaltimeAM {hour, minute :: Int, am :: Bool}
deriving Show
same :: Time -> Time -> Bool
same u1 u2 = (h u1) == (h u2)
where
h :: Time -> (Int, Int) -- (Int, Int) = (hour, minute)
h (Localtime h m) = (h, m)
h (Globaltime h m d) = ((h+d+24) `mod` 24, m)
h (LocaltimeAM h m am) = (h + (if am then 0 else 12), m)
答案 0 :(得分:15)
要回答标题中的问题:
我可以不使用
==
来使用/=
和Eq
吗?
从技术上讲,您可以在前言中显式隐藏Eq
类型类,然后自己定义(==)
和(/=)
函数,但这将是一个坏主意,因为它意味着您将无法再将两个整数与(==)
进行比较。
您可能想要使Time
成为Eq
类型类的 instance ,这样您就可以从现在开始编写time1 == time2
。我们可以将其设置为以下实例:
h :: Time -> (Int, Int) -- (Int, Int) = (hour, minute)
h (Localtime h m) = (h, m)
h (Globaltime h m d) = ((h+d+24) `mod` 24, m)
h (LocaltimeAM h m am) = (h + (if am then 0 else 12), m)
instance Eq Time where
t1 == t2 = (h t1) == (h t2)
Haskell将自动为我们编写(/=)
函数(与(==)
相反),或者您可以决定编写(/=)
版本,然后Haskell将编写{{ 1}}版本。当然,您也可以同时实现两者。
使类型成为类型类的成员实际上可能是有用的。以nub :: Eq a => [a] -> [a]
函数为例。它要求类型(==)
是a
类型类的成员,并执行某种“唯一性”过滤器:您向它提供一个元素列表,并返回一个 non列表。 -等于元素。现在,无需进行任何操作即可为您的Eq
类型定义nub
函数,通过将Time
作为Time
类型类的实例,您可以使用Eq
nub
的列表。
当然,您不能简单地将一个类型设为所有可能的类型类的实例。仅当可以检查两个项目是否相同时,才应将类型作为Time
类型类的实例(因此,当两个项目相等时,应该有一个“合理的”想法)。此外,大多数这些类型类都带有“ 合约”:例如,等式关系(如Eq
所定义的)应该是自反,对称和 transitive 。