模式匹配以获取新数据

时间:2018-08-10 19:17:05

标签: haskell pattern-matching

我创建了具有某些功能的新类型

data Gate = MakeGate (Bool -> Bool -> Bool)
andGate = MakeGate (&&)
orGate = MakeGate (||)

现在,我想将此类型添加到具有模式匹配的Eq的新实例中,但是实际上我收到了很多错误消息。到目前为止,我尝试过的是

instace Eq Gate where
    MakeGate True == MakeGate True = True

错误消息是:“无法将预期类型'Bool-> Bool-> Bool'与实际类型'Bool'相匹配” 我当时以为Bool-> Bool-> Bool的含义类似于(&&)或(||)函数。但这不是那样的。

我想念什么?

4 个答案:

答案 0 :(得分:3)

您无法在Haskell中真正实现模式匹配功能。

MakeGate是具有以下类型的构造函数:(Bool-> Bool-> Bool)-> Gate 但是,您给它的是布尔(True)。 MakeGate True不进行类型检查。

也许您是说MakeGate f == MakeGate g = f == g之类的?

我不确定您要做什么,但是功能等效并不简单,模式匹配是针对构造函数而非函数的。

我认为您真正想要的是     数据门= AndGate | OrGate | ...

答案 1 :(得分:2)

您可能想找出public void setInput(Scanner input) { this.input = input; } 数据构造函数包装的两个函数是否总是产生相同输入的相同结果。

我们只能通过穷举搜索来找到答案:对于这两个函数,计算所有可能输入的结果,并每次比较输出。因此,我们可以这样写:

MakeGate

,然后将其写为:

type GateFunc = Bool -> Bool -> Bool

eqGate :: GateFunc -> GateFunc -> Bool
eqGate f g = f False False == g False False
          && f False True == g False True
          && f True False == g True False
          && f True True == g True True

但是,上述内容并不十分优雅:我们可以通过生成列表来做得更好:

instance Eq Gate where
    MakeGate f == MakeGate g = eqGate f g

甚至更少的代码:

eqGate :: GateFunc -> GateFunc -> Bool
eqGate f g = (f <$> ft <*> ft) == (g <$> ft <*> ft)
    where ft = [False, True]

请注意,对于具有较小(至少是有限的!)输入空间且输出类型为import Data.Function(on) eqGate = on (==) ((<*> ft) . (<$> ft)) where ft = [False, True] 实例的函数,可以这样做,但是通常不能比较两个函数。此外,即使这两个函数具有有限的输入空间,也会出错(因为这两个函数可能陷入无限循环中)。确定两个函数是否相等是一个无法确定的问题。

答案 2 :(得分:1)

MakeGate不包装布尔值;它包装了 function 。我不确定如何为Eq定义Gate实例,因为您不能比较函数是否相等。但是,语法

instance Eq Gate where
    (MakeGate f) == (MakeGate g) = ???

???将是实际的相等性测试,但是就像我说的那样,不清楚要在此处输入什么内容,因为您不能使用f == g

答案 3 :(得分:1)

您无法在Eq类型上定义有意义的Gate实例,因为它包含一个函数和functions cannot be compared for equality

但是,更重要的是,您的问题似乎与Haskell的各种不同情况以及一般的高阶函数编程有关。考虑查找课程,书籍或其他资源,以有条理,有条理的方式帮助您学习。 (在Stack Overflow上讨论这些资源是不合时宜的,因此在这里我将不提出具体建议。)