Haskell 初学者问题(定义对,类似于 Http 状态)
我是 Haskell 初学者,必须定义一系列由 Int 和 String / ByteString 组成的已知状态,类似于 HTTP 状态,
我永远不需要从状态消息中获取状态代码。但是,我必须获取给定状态代码的状态消息。
我查看了 Network.HTTP.Types,它们为每个可能的状态代码定义了不同的“变量”、“status200”、“status201”等(类似于下面的“FoodTwo.hs”)。
如果我刚刚定义了一个返回状态代码的状态消息的函数(如下面的“FoodOne.hs”所示),则会产生什么(性能?)影响?
最重要的是,在像 C# 或 Java 这样的语言中,人们可能会声明一个静态字典,类似于 FoodThree.hs - 我不知何故怀疑这是 Haskell 方式?为什么?
-- FoodOne.hs
statusMessage :: Int -> String
statusMessage 30 = "BBQ ready"
statusMessage 40 = "Beverages served"
statusMessage rest = "Unknown Food Status"
-- FoodTwo.hs
data FoodStatus = FoodStatus {
fstatusCode :: Int,
fstatusMessage :: String
}
status30 = FoodStatus 30 "BBQ ready"
status40 = FoodStatus 40 "Beverages served"
-- FoodThree.hs
statusMessages = [(30,"BBQ ready"),(40,"Beverages served")]
I'm a Haskell beginner and have to define a series of known statuses that consist of an Int and a String / ByteString, similar to HTTP Statuses
I will never have to get a status code from a status message. However I will have to get a status message for a given status code.
I've had a look at Network.HTTP.Types and they define distinct 'variables', "status200", "status201", etc. for every possible status code (similar to "FoodTwo.hs" below).
What are the (performance?) implications if I just defined a function that returns status messages for status codes, as shown in "FoodOne.hs" below?
On top of that, in languages like C# or Java one would probably declare a static dictionary, similar to FoodThree.hs - I somehow doubt this is the Haskell way? Why?
-- FoodOne.hs
statusMessage :: Int -> String
statusMessage 30 = "BBQ ready"
statusMessage 40 = "Beverages served"
statusMessage rest = "Unknown Food Status"
-- FoodTwo.hs
data FoodStatus = FoodStatus {
fstatusCode :: Int,
fstatusMessage :: String
}
status30 = FoodStatus 30 "BBQ ready"
status40 = FoodStatus 40 "Beverages served"
-- FoodThree.hs
statusMessages = [(30,"BBQ ready"),(40,"Beverages served")]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
大多数编译器会将其编译为线性搜索,因此它将具有线性运行时成本。
这种方法与其他方法没有可比性:它不提供给定(动态已知)
Int
的状态查找。但是,对于静态已知的 Int,它是最快的:查找在编译时完成一次,因此无论有多少个不同的常量,都具有恒定的运行时成本。在此列表中进行简单查找(例如通过内置的
lookup
函数)将涉及线性搜索,因此具有线性运行时成本。Data.Map 模块实现了平衡搜索树,每次查找所花费的时间是不同状态数量的对数。您还可以考虑 Data.IntMap,它也需要对数时间,但具有更好的常数。
Data.Array 模块实现了不可变数组,并且每次查找都需要恒定的时间。但是,如果您的数组很稀疏,则这可能比其他方法具有更高的内存成本。
这些都是 Haskell 方式。选择一种能够在开发人员烦恼、速度和内存消耗之间进行适当权衡的语言,就像使用任何其他语言一样。
Most compilers are will compile this to a linear search, so it will have linear runtime cost.
This approach is not comparable to the others: it doesn't provide status lookup given a (dynamically-known)
Int
. However, for statically-knownInt
s, it is the fastest: the lookup is done once at compile-time and therefore has constant runtime cost, regardless of how many different constants there are.Doing naive lookup in this list (e.g. by the built-in
lookup
function) will involve linear search, and therefore have linear runtime cost.The
Data.Map
module implements balanced search trees, and each lookup takes logarithmic time in the number of different statuses. You might also considerData.IntMap
, which also takes logarithmic time, but has better constants.The
Data.Array
module implements immutable arrays, and each lookup takes constant time. If your array is sparse, however, this may have higher memory costs than the alternatives.These are all the Haskell way. Choose the one with the right tradeoffs between developer annoyance, speed, and memory consumption for you, just as you would in any other language.
这可以很容易地在 Haskell 中使用:
或者你可以使用 Data.Map:
This can easily be used in Haskell:
Or you can use Data.Map:
像下面这样的东西可以吗?
这与 FoodOne.hs 很相似,但更抽象,因此更易于操作。您可以按照自己的意愿自由地实现 fromCode,并根据需要优化性能。
Would something like the following serve?
This is pretty much FoodOne.hs but more abstract and thus more manipulable. You are free to implement fromCode however you wish, optimizing for performance as needed.