具有约束的Haskell类型同义词声明可能吗?

假设我想为Int的所有列表创建一个类型同义词.

我可以:

type NumberList = [Int]

但是如果我想调用包含数字NumberList的所有列表呢?我如何设置约束并说所有[a]只要“Num a”应该被称为相同?

编辑::看到答案后,我重新思考.看起来我反对Haskell背后的一个基本思想,奖励相对较小(只是一个正式的问题).我决定这样做:如果一个类型需要两个相同的实例,只有Int或Float不同,那么它们之间的差异太小,无法保证完成Int和Float的使用所需的解决方法但是调用他们是同一件事,这就是为什么我必须限制使用其中一个.但是,如果有一个重要的原因,为什么我应该同时拥有这两个,那么我可以在实例的名称中反映这个重要的原因,从而通过这样做来避免问题:

data Thing = Thing_A(String, String Float) | Thing_B(String,String,Int)

—从而坚持Haskell的打字系统,仍然接受它们作为数据类型Thing.我最初想做的是

data Thing = Thing(String, String, Float) | Thing(String, String, Int)

谢谢你们!

使用数据和参数,而不是存在来获取上下文

我想如果你想要的话

data Thing = Good [(Char,Int)] | Bad String | Indifferent Leg

但有时也是

data Thing = Good [(Char,Float)] | Bad String | Indifferent Arm

你可以定义

data Thing num bodypart = Good [(Char,num)] | Bad String | Indifferent bodypart

或者如果你想确保num始终是数字,你可以这样做

data Num num => Thing num bodypart = Good [(Char,num)] | Bad String | Indifferent bodypart

最后,您可以通过定义自己的类来限制bodypart中允许的类型:

class Body a where
   -- some useful function(s) here

instance Body Leg where
   -- define useful function(s) on Legs
instance Body Arm
   -- define useful function(s) on Arms

data (Num num,Body bodypart) => Thing num bodypart = 
                                                             Good [(Char,num)] | Bad String | Indifferent bodypart

我想阻止你通过forall构造函数或通过GADT使用存在类型,因为将num参数添加到数据类型在实践中更有用,即使它需要更多的输入.

类型同义词的约束?

请注意,当您使用约束时

data (Num num) => Thing num = T [(Char,num)]

实际上只是将构造函数T的类型更改为

T :: (Num num) => [(Char,num)] -> Thing num

代替T :: [(Char,num)] – >数量这意味着每次使用T时,都需要有一个上下文(Num num),但这正是您想要的 – 阻止人们将数据放入非数字的数据类型中.

这个事实的结果是你不能写

type Num num => [(Char,num)]

因为没有数据构造函数T需要上下文(Num num);如果我有[(‘4’,False)],它会自动匹配[[char,num]]类型,因为它是同义词.在确定实际类型之前,编译器不能在代码中运行查找实例.在数据的情况下,它有一个构造函数T告诉它类型,并且它可以保证有一个Num num实例,因为它检查了你对函数T的使用.没有T,没有上下文.

翻译自:https://stackoverflow.com/questions/12717301/haskell-type-synonym-declaration-with-constraint-possible

转载注明原文:具有约束的Haskell类型同义词声明可能吗?