我可以在不使用Eq的情况下使用==和/ =吗?

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]功能为例.它要求类型aEq类型类的成员,并执行某种"uniqness"过滤器:您为它提供一个元素列表,并返回一个不相等的元素列表.现在没有任何工作来nub为您的Time类型定义函数,通过创建类型类Time的实例Eq,您可以nubTimes 列表上使用.

当然,您不能简单地将类型设为所有可能类型类的实例.Eq如果你可以检查两个项是否相同,那么你应该只使类型成为类型类的实例(当两个项相等时应该有一个"合理"的想法).此外,大多数这些类型类都带有" 契约 ":例如,等式关系(如定义的(==))应该是自反的,对称的和可传递的.

  • 谢谢!这非常有帮助.你能告诉我如何在我的ghci中编译它吗? (4认同)