Bro*_*lin 3 haskell algebraic-data-types
所以我写了这个程序,一切正常;)我想改进它.我也可以使用/ =编译两个不同的时间集,结果得到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)
Run Code Online (Sandbox Code Playgroud)
Wil*_*sem 15
要回答标题中的问题:
我可以使用
==和/=不使用Eq吗?
你可以 - 从技术上讲 - 明确地隐藏Eq前奏中的类型类,然后自己定义一个(==)和(/=)函数,但这将是一个坏主意,因为它意味着你不能再比较两个整数(==).
你可能需要的是使Time一个实例中的Eq类型类,这样你可以从现在开始写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)Run Code Online (Sandbox Code Playgroud)
Haskell将自动(/=)为我们编写函数(与之相反(==)),或者您可以决定编写(/=)版本,然后Haskell将编写该(==)版本.当然你也可以实现这两个.
使类型成为类型类的成员实际上是有用的.以nub :: Eq a => [a] -> [a]功能为例.它要求类型a是Eq类型类的成员,并执行某种"uniqness"过滤器:您为它提供一个元素列表,并返回一个不相等的元素列表.现在没有任何工作来nub为您的Time类型定义函数,通过创建类型类Time的实例Eq,您可以nub在Times 列表上使用.
当然,您不能简单地将类型设为所有可能类型类的实例.Eq如果你可以检查两个项是否相同,那么你应该只使类型成为类型类的实例(当两个项相等时应该有一个"合理"的想法).此外,大多数这些类型类都带有" 契约 ":例如,等式关系(如定义的(==))应该是自反的,对称的和可传递的.