简体   繁体   English

了解Haskell类型类在类型声明中的使用

[英]Understanding Haskell Type Class use in Type Declarations

When we have a function that compares two things using the == comparison operator we add something like Eq a => a... to the type declaration; 当我们有一个使用==比较运算符比较两件事的函数时,我们在类型声明中添加类似Eq a => a...的内容; but this doesn't always seem to be the case. 但这并非总是如此。

For example, given the following function: 例如,给定以下功能:

tail' xs = if length xs == 0
          then []
          else drop 1 xs

We make use of the == comparison operator, so I assumed the correct type decalaration would be: 我们使用==比较运算符,因此我假设正确的类型声明应为:

tail':: (Eq a) => [a] -> [a]

However, running :t tail' tells me that the correct type decalartion is: 但是,运行:t tail'告诉我正确的类型十进制是:

tail':: [a] -> [a]

Why is this the case? 为什么会这样呢? Why isn't Eq required in the type declaration? 为什么在类型声明中不需要Eq

Eq a => t says that a must be an instance of Eq in the type t . Eq a => t表示a必须是类型tEq的实例。 A type being an instance of Eq means that == is defined for that type. 作为Eq实例的类型意味着为该类型定义了== But in your definition of tail' , you never use == on an a , not even by proxy. 但是,在您对tail'的定义中,您永远不会在a上使用== ,甚至也不会通过代理使用。 The actual use of == is in length xs == 0 . ==的实际用法是length xs == 0 The type of length xs (and 0 ) is Int , and Int is already an instance of Eq , so we already know it has == defined. length xs (和0 )的类型是Int ,并且Int已经是Eq的实例,因此我们已经知道它具有==定义。 Since you never use == on an a , you don't need an Eq a constraint. 由于您从未在a上使用== ,因此不需要Eq a约束。

If, however, you had said xs == [] , which seems equivalent (both test whether a list is empty), you would have incurred an Eq a constraint. 但是,如果您说xs == []似乎是等效的(都测试一个列表是否为空),则将给Eq a约束。 This is because == on [a] requires an Eq a constraint since it uses == on each list's entries to compare the lists. 这是因为[a]上的==需要一个Eq a约束,因为它在每个列表的条目上使用==来比较列表。 Since you can use length xs == 0 (or, even better, null xs ), though, this added constraint is spurious and should be avoided. 但是,由于您可以使用length xs == 0 (或者甚至更好,可以使用null xs ),因此添加的约束是虚假的,应避免。

(As an aside, drop 1 [] = [] so you don't even need your if , but that isn't relevant to the question asked.) (顺便说一句, drop 1 [] = []这样您甚至都不需要if ,但这与所问的问题无关。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM