我是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")]
Run Code Online (Sandbox Code Playgroud)
-- FoodOne.hs
statusMessage :: Int -> String
statusMessage 30 = "BBQ ready"
statusMessage 40 = "Beverages served"
statusMessage rest = "Unknown Food Status"
Run Code Online (Sandbox Code Playgroud)
大多数编译器都会将其编译为线性搜索,因此它将具有线性运行时成本.
-- FoodTwo.hs
data FoodStatus = FoodStatus {
fstatusCode :: Int,
fstatusMessage :: String
}
status30 = FoodStatus 30 "BBQ ready"
status40 = FoodStatus 40 "Beverages served"
Run Code Online (Sandbox Code Playgroud)
这种方法与其他方法不具有可比性:它不提供给定(动态已知)的状态查找Int.但是,对于静态已知的Ints,它是最快的:查找在编译时完成一次,因此具有恒定的运行时成本,而不管有多少不同的常量.
-- FoodThree.hs
statusMessages = [(30,"BBQ ready"),(40,"Beverages served")]
Run Code Online (Sandbox Code Playgroud)
在此列表中执行简单查找(例如,通过内置lookup函数)将涉及线性搜索,因此具有线性运行时成本.
-- FoodFour.hs
import Data.Map as M
statusMessages = fromList [(30, "BBQ ready"),(40,"Beverages served")]
message n = fromMaybe "Unknown Food Status" (M.lookup n statusMessages)
Run Code Online (Sandbox Code Playgroud)
该Data.Map模块实现平衡搜索树,每个查找以不同状态的数量为对数时间.您也可以考虑Data.IntMap,这也需要对数时间,但具有更好的常数.
-- FoodFive.hs
import Data.Array as A
(statusLo, statusHi) = (30, 40)
statusMessages = listArray (statusLo, statusHi)
[ Just "BBQ ready"
, Nothing
, Nothing
, {- ... -}
, Just "Beverages served"
]
message' n = guard (statusLo <= n && n <= statusHi) >> statusMessages ! n
message = fromMaybe "Unknown Food Status" . message'
Run Code Online (Sandbox Code Playgroud)
该Data.Array模块实现了不可变数组,每次查找都需要一段时间.但是,如果您的阵列很稀疏,那么这可能比替代方案具有更高的内存成本.
这些都是所有 Haskell的方式.选择一个与开发者的烦恼,速度和内存消耗之间的权衡权为你,就像你在任何其他语言.