我创建了具有某些功能的新类型
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的含义类似于(&&)或(||)函数。但这不是那样的。
我想念什么?
答案 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上讨论这些资源是不合时宜的,因此在这里我将不提出具体建议。)