在haskell中如何做到这一点?

时间:2010-11-05 13:31:23

标签: haskell erlang

我怎么能在haskell中做到这一点?

equal(S,S) -> true;
equal(S1, S2) -> {differ, S1, S2}.

1 个答案:

答案 0 :(得分:12)

Haskell有一个完全可以服务的(==)运算符来检查相等性(在定义了相等性的类型上)所以我假设你除了测试相等性之外还指的是其他东西。

我不知道Erlang,但鉴于你写了equal(S, S)我的第一个猜测是你希望模式匹配通过重用变量名来表达相等性。不幸的是,Haskell(和一般的ML风格)模式匹配不像Prolog那样强大;所有模式都可以做的是绑定变量,而不是执行完全统一。

确实存在像foo [1,2] = ...这样的常量值模式,但这只是绑定和等式检查的语法糖,而且它只针对常量值而不是变量。

通常的Haskell方法可能是模式保护,如下所示:

data EqualResult a b = Yep | Nope (a, b) deriving (Show, Eq)

equal :: (Eq a) => a -> a -> EqualResult a a
equal s1 s2 | s1 == s2  = Yep
            | otherwise = Nope (s1, s2)

如果你想要某种引用相等而不是检查相等的值,这是不可行的,因为它在Haskell中甚至没有意义。

编辑:有人向我指出,您可能也在询问有关返回不同结果类型的问题。在Haskell的任何介绍中都应该很好地使用类型,但在这种情况下的简短版本是,如果你需要返回两种可能类型中的一种,你需要一种数据类型,每种类型都有一个构造函数;然后使用模式匹配(在声明或case表达式中)检查结果。

在这种情况下,为了使它看起来更像你的函数,我创建了一个带有两个构造函数的特殊用途类型:一个表示相等(没有进一步的细节),另一个表示包含一对值的不等式。您也可以使用内置类型Either a b以通用方式执行此操作,该类型包含两个构造函数Left aRight b