例如我想做一个类型 MyType
整数三元组。但不仅仅是三个整数的笛卡尔积,我希望类型代表所有 (x, y, z) 使得 x + y + z = 5
.
我怎么做?除了只使用 (x, y)
自从 z = 5 - x - y
.
如果我有三个构造函数,同样的问题 A, B, C
并且类型应该是全部(A x, B y, C z)
这样x + y + z = 5
.
最佳答案
我认为这里的技巧是您不在类型级别强制执行它,而是使用“智能构造函数”:即仅允许通过生成此类值的函数创建此类“元组”:
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”),但它比尝试对类型级别进行某种强制限制以允许有效值(value)观。
类型可以确保正确的“类型”值(没有双关语);为了确保值的有效性,您隐藏了构造函数,并且只允许通过保证您需要的任何不变量的批准函数进行创建。
关于haskell - 如何制作有限制的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7978191/