2011-09-04 52 views
15

我想创建一个新的整数类型,它是有限的一定范围内。我曾尝试:如何创建一定范围内的类型

data PitchClass = PC Int deriving (Ord, Eq, Show) 

instance Bounded PitchClass where 
    minBound = PC 0 
    maxBound = PC 11 

但是,我想要的是什么,如果是这样

PC 12 

PC (-1) 

试图将失败。

是一种情况的一般方法,您希望在创建新的类型时创建新的类型,其中值构造函数不是从模块中导出的,而是返回该类型的实例并执行约束检查的函数出口?

回答

14

是的,不从模块中导出数据构造函数是一种方法。

相反,您可以导出一个函数来执行检查,如您所说。这通常被称为smart constructor

5

对于总数值很小的情况,另一种解决方案是简单枚举可能的构造函数。

data PitchClass = A | Bb | B | C | Db | D | Eb | E | F | Gb | G | Ab 
    deriving (Eq, Ord, Bounded, Show, Read) 

有六种不同的黑客可以从这里尝试,以便以各种方式更方便;例如,您可以导出Enum以获得toEnum . fromEnum = id(和toEnum (-1) = {- an exception -}),或者您可以编写自定义Integral实例以获得0 = A(以及您对-1的行为选择)。