Haskell 可以对公共数据类型实施约束吗?
我有以下代码:Haskell 可以对公共数据类型实施约束吗?,haskell,Haskell,我有以下代码: -- 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)
-- 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."
[[Char]]
必须为矩形(即所有子列表必须具有相同的长度),模块中的许多函数才能正常工作。在模块内部,我总是使用mkCharBox
“构造函数”,因此我不必一直强制执行此约束
最初,我希望我的模块声明如下所示:
module CharBox (
CharBox, -- No (CharBox) because it doesn't enforce rectangularity
mkCharBox
) where
但是像那样,我的模块的用户无法在CharBox
上进行模式匹配。在另一个模块中,我是这样做的
findWiresRight :: CharBox -> [Int]
findWiresRight (CharBox xs) = elemIndices '-' (map last xs)
ghci抱怨:不在范围内:数据构造函数“CharBox”
是否可以强制执行我的约束,即
CharBox
es只包含矩形数组,同时仍然允许模式匹配?(如果不可能,我想知道技术原因。我发现在探索此类约束时,Haskell通常有很多东西需要学习)最简单的解决方案是在模块中添加提取功能:
extract :: CharBox -> [String]
extract (CharBox xs) = xs
然后使用它而不是模式匹配:
findWiresRight :: CharBox -> [Int]
findWiresRight c = elemIndices '-' $ map last $ extract c
在vanilla Haskell中不可能同时隐藏构造函数和支持模式匹配 解决这一问题的通常方法是:
- ,本质上是导出模式匹配函数
- 通过将不变量移动到类型系统中
CharBox
的函数放在其模块中。有关使用视图模式隐藏构造函数并仍然支持公共数据类型上的模式匹配的信息,请参阅