Haskell没有(Eq Digit)实例使用==在表达式中:x == One

时间:2016-03-10 12:03:25

标签: haskell binary

no instance for (Eq Digit) arising from a use of == 
In the expression: x == One

这是将二进制数转换为int的简单函数的代码;当我编译它时,它给了我这个错误:

            config.Routes.MapHttpRoute(
            name: "RouteReports",
            routeTemplate: "r2/{controller}/{clientId}/{action}",
            defaults: new { action = "adherence", controller = "reports" }
            );

如果我理解得很好,也读了其他问题,问题是x不能是任何类型,但我无法理解如何解决这个问题以及如何使用Eq约束。

2 个答案:

答案 0 :(得分:8)

添加deriving子句

data Digit = Zero | One deriving (Eq)

或者不要使用==,而是使用模式匹配:

convBNum (One:xs) = 2^length xs + convBNum xs
convBNum (_  :xs) =               convBNum xs

答案 1 :(得分:6)

  

问题是x不能是任何类型

在您的代码x中有Digit类型,这正是它应具有的类型。那不是问题。

问题是==运算符是在Eq类型类中定义的。这意味着它只能用于那种类型类实例的类型,而Digit类型不是。为了使其成为一个,您可以像==一样为Digit提供instance Eq Digit where Zero == Zero = True One == One = True _ == _ = False 的定义:

Eq

但是,可以使用{{1}自动为自定义数据类型定义某些类型类(如OrdShowReadderiving)的定义}关键字,通常更可取。所以你可以写:

data Digit = Zero | One deriving Eq

这将自动生成上述Eq实例。

请注意,对于您的用例,使用嵌套模式匹配比使用==更惯用:

convBNum :: [Digit] -> Int
convBNum [] = 0
convBNum (One : xs) = 2^length xs + convBNum xs
convBNum (Zero : xs) = convBNum xs

这样您甚至不需要Eq实例,但无论如何都要有它,因为Digit是一种真正应该支持==的类型。

在不相关的说明中,您可能还应该导出或手动定义Show的实例,以便您可以print个数字并在GHCi中显示它们。