9

这里的新手,苦苦挣扎。

我正在尝试为集合定义一个类型类。对于这种情况,它只需要“存在”的定义。'exists' 将在一个集合项上接受一个集合和函数,并返回一个布尔值。我如何在 Haskell 中定义它?

下面的方向是否正确?所以有类型类定义和 set with list 的实现,'exists' 现在返回 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' 的参数太多)

4

2 回答 2

13

你可以这样做,有足够的扩展。至少,您将需要多参数类型类。但是,使用起来会很烦人:您需要在各处指定显式类型签名。解决它的一种方法是引入功能依赖项(使用另一个扩展):

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

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

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

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

于 2012-07-16T16:59:48.557 回答
7

丹尼尔瓦格纳已经对你正在尝试做的事情给出了完美的答案。我只想补充一点关于您的错误 - 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 。

于 2012-07-16T17:52:51.520 回答