Haskell:如何为集合定义类型类?

时间:2012-07-16 16:36:28

标签: haskell set typeclass

这里有新手,挣扎。

我试图为集合定义类型类。对于这种情况,它只需要定义'存在'。 '存在'将对设定项目进行设置和功能,然后返回 布尔值。我怎样才能在Haskell中定义它?

以下是否在正确的方向?所以有类型类定义和 带有列表的set的实现,其中'存在'现在返回true ..

-- Set.hs --

class Set a b where

  exists :: a -> (b -> Bool) -> Bool


-- ListSet.hs --

instance Set ListSet a where 

  exists a f = True

-

(结果:“Set'”类的参数太多了

2 个答案:

答案 0 :(得分:13)

你可以这样做,有足够的扩展。至少,您需要多参数类型类。但是,使用它会非常烦人:您需要在整个地方指定显式类型签名。修复它的一种方法是引入函数依赖(使用另一个扩展):

class Set a b | a -> b where
    exists :: a -> (b -> Bool) -> Bool

这表示如果你知道集合的类型,你也知道元素的类型。但是,有一种更简单的方法可以在没有任何扩展的情况下工作:

class Set f where
    exists :: f a -> (a -> Bool) -> Bool

在这里,类型类的范围超过了更高级的类型,这是一个巧妙的技巧,如果你以前从未见过它,很难自己想出来!

答案 1 :(得分:7)

Daniel Wagner已经就你想要做的事给出了完美的答案。我只是想补充一点关于你的错误 - Too many parameters for class 'Set'。这意味着您未启用相应的GHC扩展程序 - MultiParamTypeClasses。您可以通过在源文件顶部指定特殊类型的注释来完成此操作:

{-# LANGUAGE MultiParamTypeClasses #-}
--
-- Your source code here
--

然后你应该能够编译你的代码。

Daniel的回答中提到的另一个Haskell特性也需要启用某些扩展,即FunctionalDependencies(这是类型类声明中的奇怪的.. | a -> b ..事物)。您可以使用逗号同时启用多个扩展程序,如下所示:

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}

Carl的评论提到了另一个扩展名TypeFamilies,它还可以提供您正在尝试做的工具(集合类型或其他类型的集合)。你可以在这里阅读:http://www.haskell.org/haskellwiki/Type_families