数据系列默认实例

时间:2013-09-23 18:07:42

标签: haskell type-families

我想使用数据系列为某些数据类型创建有效的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的Bool实例发生冲突(Bool是Ord的一个实例)

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要求,可以像这样编码吗?

1 个答案:

答案 0 :(得分:5)

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