gpt4 book ai didi

具有多个参数的 Haskell 和类型类

转载 作者:行者123 更新时间:2023-12-03 15:10:07 25 4
gpt4 key购买 nike

在编写相互继承的类型类时,我遇到了一个简单的问题。我正在尝试创建类型类的层次结构以实现某种程度的表示抽象。假设我想要一个集合类型类:

{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}

class Collection c a where
isMember :: a -> c -> Bool

我已经定义了一个树类型:
data Tree a = Empty | Node a (Tree a) (Tree a)
deriving (Show, Eq)

我想让我的树成为一个集合,所以:
inOrder :: Tree a -> [a]
inOrder Empty = []
inOrder (Node a l r) = (inOrder l) ++ [a] ++ (inOrder r)

instance (Eq a) => Collection (Tree a) a where
isMember a c = a `elem` (inOrder c)

这不太正确:
*Main> (isMember '2' Empty)
<interactive>:1:1:
No instance for (Collection (Tree a) Char)
arising from a use of `isMember' at <interactive>:1:1-18
Possible fix:
add an instance declaration for (Collection (Tree a) Char)
In the expression: (isMember '2' Empty)
In the definition of `it': it = (isMember '2' Empty)

如果我必须为每个具体类型创建一个实现,那么类型类的值可能会丢失。所以我没有正确编写实例声明。但我无法完全弄清楚如何进行。

最佳答案

这里的问题是,默认情况下,每个类型类参数都独立于其他参数。只需申请isMemberChar并且未知元素类型的树不足以让它推断它应该使用(看似显而易见的)实例。

这显然不是你想要的工作方式,而且启动起来有点傻,但这就是它的工作方式。为了解决这个问题,你需要给它一些建立连接的方法,还有其他扩展:FunctionalDependencies是更常见的,而 TypeFamilies更新,更好用,但仍然有一些粗糙的边缘。

使用功能依赖项,您可以指定类型类参数的某些子集完全确定其他参数,例如Collection c a | c -> a .这有其自身的缺陷,但在许多情况下都足够好用。

对于类型族,您可能会将其简化为单参数类型类,并关联元素类型,例如:

class Collection c where
type Elem c
isMember :: Elem c -> c -> Bool

关于具有多个参数的 Haskell 和类型类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6233183/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com