Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 可以对公共数据类型实施约束吗?_Haskell - Fatal编程技术网

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
的函数放在其模块中。有关使用视图模式隐藏构造函数并仍然支持公共数据类型上的模式匹配的信息,请参阅