Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell初学者问题(定义对,类似于Http状态)_Haskell_Tuples - Fatal编程技术网

Haskell初学者问题(定义对,类似于Http状态)

Haskell初学者问题(定义对,类似于Http状态),haskell,tuples,Haskell,Tuples,我是Haskell初学者,必须定义一系列已知的状态,这些状态包括Int和String/ByteString,类似于HTTP状态 我永远不必从状态消息中获取状态代码。但是,我必须获得给定状态代码的状态消息 我看过Network.HTTP.Types,它们为每个可能的状态代码定义了不同的“变量”、“状态200”、“状态201”等(类似于下面的“FoodTwo.hs”) 如果我只是定义了一个函数,返回状态代码的状态消息,那么(性能?)会有什么影响,如下面的“FoodOne.hs”所示 除此之外,在像C

我是Haskell初学者,必须定义一系列已知的状态,这些状态包括Int和String/ByteString,类似于HTTP状态

我永远不必从状态消息中获取状态代码。但是,我必须获得给定状态代码的状态消息

我看过Network.HTTP.Types,它们为每个可能的状态代码定义了不同的“变量”、“状态200”、“状态201”等(类似于下面的“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")]

要来点什么吗

data FoodStatus = BBQ_READY | BEVERAGES_SERVED | ...

instance Show FoodStatus where ...

toCode status = ...
fromCode num = ...

这相当于FoodOne.hs,但更抽象,因此更易于操作。您可以随意实现fromCode,根据需要进行性能优化。

是否提供以下服务

data FoodStatus = BBQ_READY | BEVERAGES_SERVED | ...

instance Show FoodStatus where ...

toCode status = ...
fromCode num = ...
-- FoodThree.hs
statusMessages = [(30,"BBQ ready"),(40,"Beverages served")]
这相当于FoodOne.hs,但更抽象,因此更易于操作。您可以随意实现fromCode,根据需要优化性能

-- FoodThree.hs
statusMessages = [(30,"BBQ ready"),(40,"Beverages served")]
这可以很容易地在Haskell中使用:

fromCode n = fromMaybe "No such error" $ find ((==) n . fst) statusMessages
也可以使用数据。地图:

import qualified Data.Map as Map
import Data.Maybe (fromMaybe)

codemap = Map.fromList statusMessages

fromCode n = fromMaybe "No such error" $ Map.lookup n codemap
这可以很容易地在Haskell中使用:

fromCode n = fromMaybe "No such error" $ find ((==) n . fst) statusMessages
也可以使用数据。地图:

import qualified Data.Map as Map
import Data.Maybe (fromMaybe)

codemap = Map.fromList statusMessages

fromCode n = fromMaybe "No such error" $ Map.lookup n codemap
大多数编译器都会将其编译为线性搜索,因此会有线性运行时成本

-- FoodTwo.hs
data FoodStatus = FoodStatus {
    fstatusCode :: Int,
    fstatusMessage :: String
}

status30 = FoodStatus 30 "BBQ ready"
status40 = FoodStatus 40 "Beverages served"
-- 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)
此方法与其他方法不可比较:它不提供给定(动态已知)
Int
的状态查找。但是,对于静态已知的
Int
s,它是最快的:查找在编译时完成一次,因此具有恒定的运行时成本,而不管有多少不同的常量

-- FoodThree.hs
statusMessages = [(30,"BBQ ready"),(40,"Beverages served")]
在此列表中执行简单查找(例如,通过内置的
lookup
函数)将涉及线性搜索,因此具有线性运行时成本

-- FoodTwo.hs
data FoodStatus = FoodStatus {
    fstatusCode :: Int,
    fstatusMessage :: String
}

status30 = FoodStatus 30 "BBQ ready"
status40 = FoodStatus 40 "Beverages served"
-- 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)
Data.Map
模块实现了平衡的搜索树,每次查找都需要对数时间来表示不同状态的数量。你也可以考虑<代码>数据.ItMult,它也需要对数时间,但有更好的常量。
-- 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'
——FoodFive.hs
将Data.Array作为
(statusLo,statusHi)=(30,40)
statusMessages=listArray(statusLo、statusHi)
[只要“准备烧烤”
,没什么
,没什么
, {- ... -}
,只是“提供饮料”
]
消息'n=防护(状态LO状态消息!n
message=可能来自“未知食物状态”。message'
Data.Array
模块实现不可变数组,并且每次查找都需要固定的时间。但是,如果您的数组是稀疏的,则这可能比其他方法的内存成本更高

这些都是Haskell的方法。选择一种在开发人员烦恼、速度和内存消耗之间进行适当权衡的方法,就像在其他语言中一样

大多数编译器都会将其编译为线性搜索,因此会有线性运行时成本

-- FoodTwo.hs
data FoodStatus = FoodStatus {
    fstatusCode :: Int,
    fstatusMessage :: String
}

status30 = FoodStatus 30 "BBQ ready"
status40 = FoodStatus 40 "Beverages served"
-- 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)
此方法与其他方法不可比较:它不提供给定(动态已知)的状态查找
Int
。但是,对于静态已知的
Int
s,它是最快的:查找在编译时完成一次,因此具有恒定的运行时成本,而不管有多少不同的常量

-- FoodThree.hs
statusMessages = [(30,"BBQ ready"),(40,"Beverages served")]
在此列表中执行简单查找(例如,通过内置的
lookup
函数)将涉及线性搜索,因此具有线性运行时成本

-- FoodTwo.hs
data FoodStatus = FoodStatus {
    fstatusCode :: Int,
    fstatusMessage :: String
}

status30 = FoodStatus 30 "BBQ ready"
status40 = FoodStatus 40 "Beverages served"
-- 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)

>代码>数据.MAP< /Cult>模块实现平衡搜索树,每个查找在不同状态的数目中取对数时间,也可以考虑<代码>数据.Itmap < /C> >,它也需要对数时间,但具有更好的常量。

-- 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'
——FoodFive.hs
将Data.Array作为
(statusLo,statusHi)=(30,40)
statusMessages=listArray(statusLo、statusHi)
[只要“准备烧烤”
,没什么
,没什么
, {- ... -}
,只是“提供饮料”
]
消息'n=防护(状态LO状态消息!n
message=可能来自“未知食物状态”。message'
Data.Array
模块实现不可变数组,并且每次查找都需要固定的时间。但是,如果您的数组是稀疏的,则这可能比其他方法的内存成本更高


这些都是Haskell的方法。选择一个在开发人员烦恼、速度和内存消耗之间进行适当权衡的方法,就像在任何其他语言中一样。

这很有趣,我的印象是,一旦计算了表达式,它将缓存在Haskell中,因此变量1和应与变量2相似。同样,对于“status200”,通过“statusMessage status200”访问状态消息与第一个“statusMessage 200”有多相似?@kitsune大多数编译器只有在程序员明确要求时才进行缓存——例如,当他们通过let绑定、where绑定或顶级定义创建数据结构时——因为很难自动分析缓存的内存成本何时会得到回报。至于你的另一个问题,在
FoodTwo.hs
中de>fstatusMessage函数本质上是一个指针解引用——它是一个常量时间操作。这非常有趣,我的印象是,一旦计算了表达式,它将缓存在Haskell中,因此变量1之间的性能应该与变量2类似。此外,还有“status200”,通过“statusMessage status200”访问状态消息与第一个“statusMessage 200”访问状态消息的相似程度如何?@kitsune大多数编译器只有在程序员明确请求时才进行缓存——例如,当它们通过let绑定、where绑定或顶级定义创建数据结构时——因为当缓存的内存成本降低时,很难自动进行分析