2013-09-23 75 views
4

我想使用数据族为某些数据类型创建高效的Set表示。对于所有其他(Ord)数据类型,我想使用Data.Set作为实例。值得注意的是,在这种情况下,我不希望显式实例化每种类型的数据类。相反,我想要一个涵盖其余类型的一般实例。数据族默认实例

例子:

{-# LANGUAGE TypeFamilies #-} 

module Test where 

import qualified Data.Set as D 

class SetKey a where 
    data Set a :: * 
    empty :: Set a 
    insert :: a -> Set a -> Set a 
    member :: a -> Set a -> Bool 
    toList :: Set a -> [a] 

instance SetKey Bool where 
    data Set Bool = BoolSet Bool Bool 
    empty = BoolSet False False 
    insert x (BoolSet t f) = case x of 
     True -> BoolSet True f 
     False -> BoolSet t True 
    member x (BoolSet t f) = case x of 
     True -> t 
     False -> f 
    toList (BoolSet t f) = if t && f 
     then [True, False] 
     else if t 
      then [True] 
      else if f 
       then [False] 
       else [] 

我知道下面不无UndecidableInstances工作。即便如此,这将导致与布尔实例冲突的setkey的(布尔是奥德的一个实例)

instance (Ord a) => SetKey a where 
    newtype Set a = Wrap { unWrap :: D.Set a } 
    empty = Wrap . D.empty 
    insert x = Wrap . D.insert x . unWrap 
    member x = Wrap . D.member . unWrap 
    toList = D.toList . unWrap 

我怎么会去解决这样的问题?我试过直接将默认为数据家庭类的定义,但无论是我无法找出语法或功能根本不存在:

class SetKey a where 
    data Set a :: * 
    data Set a = D.Set a 
    empty :: Set a 
    empty = D.empty 
    insert :: a -> Set a -> Set a 
    insert = D.insert 
    member :: a -> Set a -> Bool 
    member = D.member 
    toList :: Set a -> [a] 
    toList = D.toList 

如果代码永远不能正常工作,我该怎么办呢?如果Data.Set没有Ord需求,可以像这样工作代码?

回答

5

默认数据族没有意义,因为您必须声明数据类型的构造函数,并且不能为不同类型使用相同名称的构造函数。您不能像您在上一个示例中那样将数据族用作类型族。

+0

您是否暗示类型族(或类型族和数据族的混合体)可以做我想要的?如果是这样,你能澄清一下吗? –

+0

将数据族更改为类型族时,您会遇到哪些问题? –

+0

从头开始,你是对的。谢谢 –