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

ter*_*ero 8 haskell set typeclass

在这里总新手,苦苦挣扎.

我正在尝试为集合定义类型类.对于这种情况,它只需要'exists'的定义.'exists'将在set项上设置一个set和function,并返回一个布尔值.我怎样才能在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
Run Code Online (Sandbox Code Playgroud)

-

(结果:"Set"类的参数太多)

Dan*_*ner 13

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

class Set a b | a -> b where
    exists :: a -> (b -> Bool) -> Bool
Run Code Online (Sandbox Code Playgroud)

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

class Set f where
    exists :: f a -> (a -> Bool) -> Bool
Run Code Online (Sandbox Code Playgroud)

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

  • 谢谢!我得到了第二种工作方式!我必须承认,我不太明白那里发生了什么,但希望它向我展示...... (2认同)

Vla*_*eev 7

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

{-# LANGUAGE MultiParamTypeClasses #-}
--
-- Your source code here
--
Run Code Online (Sandbox Code Playgroud)

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

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

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
Run Code Online (Sandbox Code Playgroud)

卡尔的评论提到了另一个扩展,TypeFamilies它也可以提供你想要做的工具(通用类集合类型或其他类型的集合).你可以在这里阅读:http://www.haskell.org/haskellwiki/Type_families.