21

我对 Haskell 还是很陌生(断断续续地学习它)。我想知道为什么 Haskell 没有文字Data.Map构造函数语法,例如 Clojure 或 Ruby 中的 Map/Hash 构造函数语法。有原因吗?我认为由于 Haskell 确实有一个文字构造函数语法 for Data.List,所以应该有一个 for Data.Map

这个问题根本不是批判的。我只想通过答案了解更多关于 Haskell 的信息。

4

5 回答 5

18

与 Clojure 和 Ruby 不同,Haskell 的有限映射是作为库提供的。这需要权衡取舍:例如,正如您所注意到的,有限映射没有内置语法;然而,因为它是一个库,我们可以(并且确实)有许多替代实现,作为程序员,您可以选择最适合您使用的实现。

于 2012-05-28T14:27:28.203 回答
13

除了已经给出的答案(尽管是“历史事故”),我认为与在 Ruby 或类似事物Data.Map中相比,在 Haskell中的使用还有一些话要说;Hash其他语言中的类似地图的对象往往更多地用于一般的临时存储。

而在 Haskell 中,您data可以立即做出定义,而在其他语言中创建类往往有点重量级,因此我们发现即使对于具有众所周知结构的数据,我们也只会使用一个Hashdict或类似的。事实上,我们有一个直接的语法来做到这一点,这使得它成为一个更具吸引力的选择。

与 Lisp 相比:使用MAKE-HASH-TABLE然后重复SETFing 它相对烦人(类似于 using Data.Map),因此所有内容都被扔进嵌套列表中,因为它很方便。

同样,我很高兴存储数据最方便的选择是创建适合的新类型,然后Data.Map在我实际构建映射或哈希表作为内在组件时留待。在某些情况下,我认为语法会很好(通常只适用于较小的一次性程序),但总的来说我不会错过它。

于 2012-05-29T10:49:34.013 回答
8

实际上我不确定为什么没有人在答案中指出它(只有 sam boosalis 的评论)但是OverloadedLists你几乎可以得到Mapand的字面语法Set

{-# LANGUAGE OverloadedLists #-}

import Data.Map
import Data.Set

foo :: Map Int Int
foo = [(1,2)]

bar :: Set Int
bar = [1]

从那里开始,只需再迈出一步即可获得更好看的地图,例如:

a =: b = (a,b)

ages :: Map String Int
ages = [ "erik"  =: 30
       , "john"  =: 45
       , "peter" =: 21 ]

虽然我个人更喜欢显式而不是隐式,所以除非我正在构建一个 DSL,否则我仍然会坚持fromList并且(foo, bar)- Haskell 是关于大胜利而不是小胜利。

于 2016-01-05T13:17:59.783 回答
7

Haskell 对列表有特殊的语法,因为在惰性函数语言中,它们或多或少地取代了命令式语言中的循环控制结构。因此,它们比Map宏伟计划中的重要得多。

另外,我知道你[1,2,3]说的是“列表语法”,但我想补充一点,列表构造函数语法几乎可以在 haskell-98 中实现,因为类型构造函数在以 开头时可以是中缀:,例如

data Pair = Int :-- Int

所以列表构造函数:只是这个通用语法规则的一个特例,它非常优雅。有些人错过了这一点。

于 2012-05-28T16:30:27.130 回答
0

Haskell 确实有一个 Map 构造函数,但它是“隐藏的”(就像面向对象范例中的私有方法一样)。鼓励您使用“公共”构造函数,例如emptysingletonfromList。但是,如果您检查https://hackage.haskell.org/package/containers-0.4.0.0/docs/src/Data-Map.html上提供的代码,您会得到以下定义

data Map k a  = Tip
              | Bin {-# UNPACK #-} !Size !k a !(Map k a) !(Map k a)

您可以使用TipBin构造函数,但不建议这样做。

于 2015-03-02T17:36:28.723 回答