例如,我想创建一个整数三元组的类型MyType。但不只是三个整数的笛卡尔乘积,我希望类型表示所有(x,y,z),这样x + y + z = 5。
我该怎么做?除了从z = 5 - x - y开始只使用(x, y)。
同样的问题,如果我有三个构造器A, B, C,类型应该都是(A x, B y, C z),这样x + y + z = 5。
发布于 2011-11-02 17:50:50
我认为这里的诀窍是你不在类型级别强制它,你使用“智能构造函数”:即只允许通过生成这样的值的函数来创建这样的“元组”:
module Test(MyType,x,y,z,createMyType) where
data MyType = MT { x :: Int, y :: Int, z :: Int }
createMyType :: Int -> Int -> MyType
createMyType myX myY = MT { x = myX, y = myY, z = 5 - myX - myY }如果您希望生成所有可能的此类值,则可以编写一个函数来实现此目的,可以使用提供的或指定的界限。
可以很好地使用类型级别的教堂数字或一些类似的数字来强制创建这些数字,但对于您可能想要/需要的内容来说,这几乎肯定是太多的工作。
这可能不是您想要的(即“除了只使用(x,y),因为z=5-x- y"),但它比试图在类型级别上强制限制允许有效值更有意义。
类型可以确保值的正确“类型”(没有双关语);为了确保值的有效性,您可以隐藏构造函数,并且只允许通过经过批准的函数创建,以保证所需的任何不变量。
https://stackoverflow.com/questions/7978191
复制相似问题