几年前,我读到Haskell如何比较布尔表达式,我想看看我是否可以在我的项目(F#)中使用相同的概念,但我不明白它是如何工作的:
来源:https://hackage.haskell.org/package/ghc-prim-0.10.0/docs/src/GHC.Classes.html#%3D%3D
x /= y = not (x == y)
x == y = not (x /= y)
这完全有道理,但它怎么不会以一个永无止境的递归结束呢?
背景:在我的项目中,我有花费和未花费的硬币,我认为它们可以类似于布尔值来处理,当一个硬币没有花费时,它是未花费的,当它没有花费时,它是花费的。
3条答案
按热度按时间ego6inou1#
这些是
Eq
类型类的默认方法。这意味着,如果某个类型示例化了Eq
,但没有提供==
的实现,它将被定义为not (x /= y)
。如果它不提供/=
的实现,则将其定义为not (x == y)
。如果它没有提供任何一个方法的实现,你将得到无限的递归。还要注意这两行之后的
{-# MINIMAL (==) | (/=) #-}
注解。这意味着“Eq
的最小实现将定义==
或/=
“,并指示编译器在创建没有定义至少一个这些方法的示例时产生警告。dfddblmv2#
如果你像那样声明普通函数,它会无限循环。但在这种情况下,这些只是类方法的默认定义。该类的每个特定示例都应该至少覆盖其中一个(
{-# MINIMAL (==) | (/=) #-}
就是这么说的)。这种情况是《油污损害民事责任公约》一项提案的主题:https://github.com/haskell/core-libraries-committee/issues/3。所以将来这种情况可能会通过简单地从类中删除
(/=)
方法并使其成为一个单独的函数来解决。9w11ddsr3#
这完全有道理,但它怎么不会以一个永无止境的递归结束呢?
这是一个类型类,示例应该做一个实现。你所看到的是一个默认的(回退)实现。
实际上,编译器通常会强制这样做。该类不仅提供函数签名和默认实现,还显示:
最小值意味着类型类的示例必须实现
(==)
或(/=)
(它们当然可以实现两者)。对于
Eq
的任何有意义的示例也是如此,例如Int
:其中
eqInt
和neInt
在这种情况下实现为:然后,这些函数具有
==#
函数,可以处理 * 未装箱的 *Int#
值。注意Haskell中的一个 class 是一个 typeclass,这看起来更像是面向对象编程中的一个 interface。它不处理(具体的)数据,它只是提供了一个应该实现的接口。