哈斯克尔:我怎样才能为集合定义一个类型类



这里完全是新手,正在挣扎。

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

以下内容的方向是否正确?因此,存在类型类定义和具有列表的集合的实现,其"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"的参数太多)

您可以通过这种方式来实现,并有足够的扩展。至少,您需要多个参数类型类。然而,使用它会非常麻烦:您需要在各处指定显式类型签名。修复它的一种方法是引入一个功能依赖(使用另一个扩展):

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

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

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

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

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.

最新更新