我想定义一个函数,<-?来检查一个元素是否在list/set/map中.
module Test where
import qualified Data.Map as Map
import qualified Data.Set as Set
class Memberable a where
(<-?) :: b -> a -> Bool
instance Memberable [x] where
(<-?) = elem
instance Memberable (Map.Map k v) where
(<-?) = Map.member
instance Memberable (Set.Set x) where
(<-?) = Set.member
Run Code Online (Sandbox Code Playgroud)
b类声明中的类型变量应该是我想要检查的元素的类型.但是,这对Haskell不起作用.
Test.hs:8:13:
Couldn't match type 'b' with 'x'
'b' is a rigid type variable bound by
the type signature for (<-?) :: b -> [x] -> Bool at Test.hs:8:5
'x' is a rigid type variable bound by
the instance declaration at Test.hs:7:10
Expected type: b -> [x] -> Bool
Actual type: b -> [b] -> Bool
Relevant bindings include
(<-?) :: b -> [x] -> Bool (bound at Test.hs:8:5)
In the expression: elem
In an equation for '<-?': (<-?) = elem
Run Code Online (Sandbox Code Playgroud)
我如何b在类声明中使用,但仍然使类型重合?
TypeFamilies问题是你必须以某种方式连接b你的集合(其中的元素) - 有几种方法可以做到这一点,但我认为一个相当不错的方法是使用TypeFamilies:
{-# LANGUAGE TypeFamilies #-}
module Test where
import qualified Data.Map as Map
import qualified Data.Set as Set
class Memberable a where
type ElemT a :: *
(<-?) :: (ElemT a) -> a -> Bool
instance Eq x => Memberable [x] where
type ElemT [x] = x
(<-?) = elem
instance Ord k => Memberable (Map.Map k v) where
type ElemT (Map.Map k v) = k
(<-?) = Map.member
instance Ord x => Memberable (Set.Set x) where
type ElemT (Set.Set x) = x
(<-?) = Set.member
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我在类中添加了一个附加type 成员,该成员将保存所使用元素的类型(因此您可以(<-?)在下一行中使用它们).
我还为你的实例添加了所需的约束 - 那些实际上来自使用的函数,比如elem,Map.member和Set.member.
MultiParamTypeClasses这是@dfeuer暗示的(或者我认为):
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
module Test where
import qualified Data.Map as Map
import qualified Data.Set as Set
class Memberable e a where
(<-?) :: e -> a -> Bool
instance Eq x => Memberable x [x] where
(<-?) = elem
instance Ord k => Memberable k (Map.Map k v) where
(<-?) = Map.member
instance Ord x => Memberable x (Set.Set x) where
(<-?) = Set.member
Run Code Online (Sandbox Code Playgroud)
我认为使用这种方法你也可能想要添加它FunctionalDependency,因为你明确地在集合a和它的元素之间有这样的依赖关系e;)
{-# LANGUAGE FunctionalDependencies #-}
class Memberable e a | a -> e where
(<-?) :: e -> a -> Bool
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
179 次 |
| 最近记录: |