[英]Haskell Ord instance with a Set
我有一些代码想用于将边缘附加到Node数据结构中:
import Data.Set (Set)
import qualified Data.Set as Set
data Node = Vertex String (Set Node)
deriving Show
addEdge :: Node -> Node -> Node
addEdge (Vertex name neighbors) destination
| Set.null neighbors = Vertex name (Set.singleton destination)
| otherwise = Vertex name (Set.insert destination neighbors)
但是,当我尝试编译时,出现此错误:
No instance for (Ord Node)
arising from a use of `Set.insert'
据我所知,Set.insert期望的只是一个值和一个要插入其中的集合。 这是什么奥德?
在GHCi中:
> import Data.Set
> :t insert
insert :: (Ord a) => a -> Set a -> Set a
所以是的,它确实期望Ord
。 至于Ord
含义,它是有序值的类型类 。 在这种情况下,这是必需的,因为Data.Set
使用搜索树,因此需要能够比较值以查看哪个更大或它们是否相等。
几乎所有标准的内置数据类型都是Ord
实例,而列表,元组, Maybe
等之类的东西则是其类型参数为Ord
实例。 当然,最显着的例外是函数,在这些函数中无法定义任何合理的排序概念(甚至相等性)。
在许多情况下,可以在声明后使用deriving
子句为自己的数据类型自动创建类型类的实例:
data Foo a = Foo a a Int deriving (Eq, Ord, Show, Read)
对于参数化类型,自动派生取决于类型参数(也就是实例),例如列表,元组等。
除了Ord
之外,一些重要的类型类还包括Eq
(相等比较,但不小于/大于), Enum
(您可以枚举其值的类型,例如对Integer
计数)和Read
/ Show
(使用字符串进行简单的序列化/反序列化)。 要了解有关类型类的更多信息,请在Real World Haskell中尝试本章,或者,有关更一般的概述,请参见 Wikipedia文章 。
Haskell集基于搜索树。 为了将元素放入搜索树中,必须给出元素的排序。 您可以通过将Ord添加到数据声明中来派生Ord,就像派生Show一样,即:
data Node = Vertex String (Set Node)
deriving (Show, Eq, Ord)
您可以通过Data.Set.insert的签名看到Ord的要求
(Ord a) => a -> Set a -> Set a
部分(Ord a) =>
建立一个约束存在的类型类的一个实例Ord
为a
。 haskell教程中 有关类型类的部分提供了更全面的说明。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.