繁体   English   中英

具有Set的Haskell Ord实例

[英]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) =>建立一个约束存在的类型类的一个实例Orda haskell教程中 有关类型类部分提供了更全面的说明。

暂无
暂无

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

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