我不了解Map.map(Data.Map中的地图功能)和Map.fromList的签名。函数本身在签名中。我也不确定为什么要实现其他功能(例如Map.member或Map.filter或Map.size)时总是调用Map.fromList。就像为什么我不能直接在列表上应用该功能,而不得不通过Map.fromList间接应用它。
fromlist的最后但并非最不重要的签名。我注意到被调用的Map.Map函数具有大写的M而不是小的m(关闭了第二行)(参考第二行的Map.map)。
非常感谢
Map.fromList :: Ord k => [(k, a)] -> Map.Map k a
Map.map :: (a -> b) -> Map.Map k a -> Map.Map k b
fromList' :: (Ord a) => [(a,b)] -> Map.Map a b
fromList' = foldl (\acc (a,b) -> Map.insert a b acc) Map.empty
答案 0 :(得分:11)
哇,看起来您很困惑。这是可以理解的,因为“地图”一词至少意味着四种不同的东西!
Data.Map
模块(您对此似乎很清楚)Map.Map k v
(在Data.Map
模块中),它是一个有限映射,又名“字典”,又名“哈希表”(但它没有)不要使用哈希)Map.map
(在Data.Map
模块中),该函数将函数应用于Map
(词典)中的每个值map
中的标准Prelude
函数可用于列表,与Map
s(词典)无关。哇,真是满嘴!
以下是对签名的一些解释:
Map.fromList :: (Ord k) => [(k, a)] -> Map.Map k a
Map.Map k a
是带有两个参数k
和a
的参数化数据类型。如果您熟悉C ++系列中的泛型,则可以写成Map<K, A>
。
fromList
函数获取(键,值)对[(k, a)]
的列表,并返回字典。字典的键的类型为k
,而值的类型为a
。 (Ord k)
意味着键必须相对于彼此是可排序的,因为它将数据结构存储为排序的平衡树。
-- A dictionary from people's names to their age
ages :: Map.Map String Int
ages = Map.fromList [("Bill", 32), ("Carol", 71), ("Diddy", 13)]
Map.map :: (a -> b) -> Map.Map k a -> Map.Map k b
这将从a
类型的事物到b
类型的事物的函数作为其第一个参数。作为其第二个参数,它将字典从任何键类型k
到类型a
的事物,并将该函数应用于字典中的每个值,从而将相同键类型的字典返回给事物b
类型的。
-- A dictionary from people's names to whether they are allowed to drink alcohol
canDrink :: Map.Map String Bool
canDrink = Map.map (\age -> age >= 21) ages
fromList'
只是fromList
的自定义实现,通过重复插入来实现。毫无疑问,它具有与fromList
相同的签名(但是类型变量的命名不同-这没有区别)。