现在,我正在学习Haskell,并尝试将我的数据(可能类似于Eq )作为一个实例,如下所示。
module Main where
data MyMaybe a = MyNothing | MyJust a
instance (Eq a) => Eq (MyMaybe a) where
MyNothing == MyNothing = True
MyJust x == MyJust y = x == y
_ == _ = False
main :: IO ()
main = do
let b0 = MyJust 42 == MyJust 42 -- OK
print b0 -- True
let b1 = MyNothing == MyNothing -- Build error!
print b1但是编译器返回行let b1 = MyNothing == MyNothing中的一个错误,如下所示。
另一种方法是用“=”中转站、中转站、转轨机、可发性固定:使用一种转轨型、转制型、转轨式批注,指定再转轨、转轨等。另外,还存在着这些潜在的转制实例,即“GHC.Classes.These”中所定义的等价物(Eq)、转码(Eq)、转位(Eq)、转码(Eq)、无价(Eq)、转码(Eq)、转码(Eq)、再转制(Eq)、无价(Eq)等。 ..。
我怎么才能修好它?
..。我已经搜索了现有的问题和答案。下面的一个似乎接近我的,但我认为我的代码已经解决了问题的答案。
发布于 2017-08-27 10:29:53
问题是MyMaybe是一个参数化类型,但是在表达式MyNothing == MyNothing中,编译器无法确定您是指MyMaybe Int、MyMaybe String、MyMaybe (Int -> Bool)还是其他什么。
您可以使用这样的类型注释来帮助它:
let b1 = MyNothing == (MyNothing :: MyMaybe Int)发布于 2017-08-27 10:34:22
问题是,MyNothing的类型是MyMaybe a,对a可以是什么没有任何限制。
编写MyNothing == MyNothing时,(==) :: (Eq b) => b -> b -> Bool类型将两个MyNothing限制为相同类型(编译器最初以MyNothing :: MyMaybe a0和MyNothing :: MyMaybe a1开头,但随后实现了a0 == a1)。
但是要解决==本身,编译器需要找到正确的Eq实例(因为这是定义==的地方)。我们的类型是MyMaybe a,这很好:我们有一个Eq (MyMaybe a)实例。但是它也需要一个Eq a实例,因为我们不知道a是什么,所以不能解决这个实例。( (Eq a)没有在MyNothing == MyNothing中实际使用并不重要;类型检查不注意运行时值。)
这就是编译器放弃的地方,说它不能解决约束(Eq a0),因为类型变量a0是不明确的。
修这个很容易。只需提示编译器应该使用哪种类型:
let b1 = MyNothing == (MyNothing :: MyMaybe Integer) -- for example或者:
let b1 = MyNothing == (MyNothing :: MyMaybe (Double, [String]))实际类型并不重要(只要它有一个Eq实例)。
这种模糊性不限于您的MyMaybe类型。您应该得到与Maybe (Nothing == Nothing)或[] ([] == [])相同的错误。在所有情况下都涉及一个多态常数(Nothing :: Maybe a,[] :: [a])。
你的例子在ghci中确实有效。这是因为ghci使用扩展违约规则并最终将a转换为();也就是说,比较是以MyNothing == (MyNothing :: MyMaybe ())的形式进行的。
https://stackoverflow.com/questions/45903799
复制相似问题