Haskell 基于数据映射的模式匹配

Haskell 基于数据映射的模式匹配,haskell,Haskell,我做了一次搜索,但令人惊讶的是,没有找到任何能帮助我在上面执行模式匹配的东西。我需要确保在我的映射“变量”中正好有3个键。就这样。我想使用模式匹配,而不是“如果……那么……否则”,因为它更容易阅读,而且似乎更像haskell的方式。因此: myFunction :: Map String String --....................... main = do let var1 = myFunction -- how do I ensure it has exactly 3

我做了一次搜索,但令人惊讶的是,没有找到任何能帮助我在上面执行模式匹配的东西。我需要确保在我的映射“变量”中正好有3个键。就这样。我想使用模式匹配,而不是“如果……那么……否则”,因为它更容易阅读,而且似乎更像haskell的方式。因此:

myFunction :: Map String String
--.......................

main = do
  let var1 = myFunction
  -- how do I ensure it has exactly 3 keys in it and if not raise an error?  

您无法对抽象数据类型进行模式匹配,因为您无法访问它们的构造函数,因此必须使用“data.Map”模块提供的函数

但是请注意,您可以使用一个
size::mapka->Int
函数。如果你不喜欢,
if。。然后。。else.
(这绝不是错误的或不正确的),您可以使用图案保护:

foo m | size m == 3 = ...
      | otherwise = error "Not three element"

在这里不考虑视图模式和模式同义词,但这些只是语法上的补充。

您可以在
M.toList
上进行模式匹配:

import qualified Data.Map as M
-- ...
main = do
  case (M.toList myFunction) of
    [a,b,c] -> ... -- exactly 3 arguments
    _       -> ... -- more or less than 3 arguments

通常我会说
size
length
是非Haskellish,但在这里,这可以说是正确的做法。为什么它是一个抽象数据类型?导出类型的模块也不会导出其构造函数。如果需要,您可能会构建无效的搜索树,然后
Map
函数会突然给出错误的结果。好的。有没有办法一次获得这3个值?如果有任何非Haskell wayish的东西,那么可能你有一个函数,它只在特定大小的地图上工作。很可能您的类型与您需要的不匹配。我如何知道哪个值对应于哪个键?a、b和c是一个元组
(键、值)
@AlexanderSupertramp您不会,
映射
不会保留顺序,因为它们使用比类型
[(键、值)]
更有效的实现,IIRC它是一个二进制搜索树,但是,您必须查看
toList
的源代码,以确定返回的顺序。简言之,没有一个好方法可以确定哪些是哪些。如果您需要该功能,我建议您只需(查找您需要的每个元素)()。如果在
映射中找不到这三个键,此示例将保留顺序并返回
Nothing