问题描述
- 一个CharBox是一个矩形的字符矩阵
data CharBox = CharBox [String]
派生Show
- 构建一个CharBox,确保内容是矩形的
mkCharBox :: [String] - > CharBox
mkCharBox [] = CharBox []
mkCharBox xxs @(x:xs)= if(all(\ s - >(length s)== length x)xs)
那么CharBox xxs
else错误CharBox必须是矩形。
[[Char]]
必须是矩形(即所有子列表必须具有相同的长度)才能使模块中的许多功能正常工作。在模块内部,我总是使用 mkCharBox
构造函数,所以我不必一直执行这个约束。
最初我想让我的模块声明如下所示:
module CharBox(
CharBox, - - 否(CharBox),因为它不强制矩形
mkCharBox
)其中
CharBox 上模式匹配。在另一个模块中,我做了
findWiresRight :: CharBox - > [b] b
findWiresRight(CharBox xs)= elemIndices' - ' >和ghci抱怨:不在范围内:数据构造函数'CharBox'
是否可以强制执行我的约束条件是 CharBox
es只包含矩形数组,但仍允许模式匹配?(如果这不可行,我会对知道技术感兴趣原因为什么我发现在探索这些限制时,Haskell通常会学到很多东西)
解决方案都隐藏了构造函数和支持模式匹配。
解决这个问题的常用方法是:
$ ul
,实质上是导出模式匹配功能。
或:
- 将不变量移动到th e类型系统通过。
I have the following code :
-- A CharBox is a rectangular matrix of characters
data CharBox = CharBox [String]
deriving Show
-- Build a CharBox, ensuring the contents are rectangular
mkCharBox :: [String] -> CharBox
mkCharBox [] = CharBox []
mkCharBox xxs@(x:xs) = if (all (\s -> (length s) == length x) xs)
then CharBox xxs
else error "CharBox must be a rectangle."
The [[Char]]
must be rectangular (i.e. all sub-lists must have the same length) for many functions in the module to work properly. Inside the module I'm always using the mkCharBox
"constructor" so I don't have to enforce this constraint all the time.
Initially I wanted my module declaration to look like this :
module CharBox (
CharBox, -- No (CharBox) because it doesn't enforce rectangularity
mkCharBox
) where
But like that, users of my module cannot pattern match on CharBox
. In another module I do
findWiresRight :: CharBox -> [Int]
findWiresRight (CharBox xs) = elemIndices '-' (map last xs)
And ghci complains: Not in scope: data constructor 'CharBox'
Is it possible to enforce my constraint that CharBox
es contain only rectangular arrays, while still allowing pattern matching ? (Also if this is not possible, I'd be interested in knowing the technical reason why. I find there's usually a lot to learn in Haskell when exploring such restrictions)
解决方案 It's not possible in vanilla Haskell to both hide the constructors and support pattern matching.
The usual approaches to address this are:
- view patterns, essentially, export the pattern matching functions.
or:
- move the invariant into the type system via size types.
这篇关于公共数据类型可以约束吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!