我正在读《学习哈斯凯尔》,这本书使我感到困惑,其中一个例子使我感到困惑,您可以看到例子here
import qualified Data.Map as Map
data LockerState = Taken | Free deriving (Show, Eq)
type Code = String
type LockerMap = Map.Map Int (LockerState, Code)
lockerLookup :: Int -> LockerMap -> Either String Code
lockerLookup lockerNumber map = case Map.lookup lockerNumber map of
Nothing -> Left $ "Locker" ++ show lockerNumber ++ "doesn't exist"
Just (state, code) -> if state /= Taken
then Right code
else Left $ "Locker" ++ show lockerNumber ++ "is already taken"
{-
lookup :: Ord k => k -> Map k a -> Maybe a
Lookup the value at a key in the map.
The function will return the corresponding value as (Just value), or Nothing if the key isn't in the map.
-}
-- The "::" can be read "has type."
lockers :: LockerMap
lockers = Map.fromList
[(100,(Taken, "ZD39I"))
,(101,(Free, "JAH3I"))
,(103,(Free, "IQSA9"))
,(105,(Free, "QOTSA"))
,(109,(Taken, "893JJ"))
,(110,(Taken, "99292"))
]
但是Nothing -> Left
的特定行使我感到困惑。首先,我想知道箭头的确切含义(我可以想象它的含义,但是我想要更多的“学术”内容)
另一部分是单词Left
和Right
,我不知道他们是否像map
那样使用它,起初看起来像一个函数,但它只是一个变量名,或者用作代码。在那种情况下,他们真正做什么?
更新
我发现here对“任一”都有很好的解释。我将其放在此处作为对我有同样疑问的任何人的参考(请转到“也许比可能更好”)。我将摘录一段文字,为我提供所需的最终线索,以防日后该页面消失。
“谈论错误处理'也许'有点局限。我们对失败的了解仅是它发生了。实际上,我们想了解更多。因此,错误处理的下一步是使用'要么。
这两种参数中的任何一种都不是。 Either类型的值包含a类型或b类型的值。我们可以通过在任一构造函数上进行模式匹配来区分这两种可能性。这两种方法都可以用作Maybe的概括,其中Left不仅编码失败,还伴随错误消息。正确编码成功及其伴随的价值。”
答案 0 :(得分:4)
标识符Nothing
和Just
是Maybe
类型的数据构造函数,其给出方式为:
data Maybe a = Nothing | Just a
数据构造函数使您可以在两个方向上工作。您可以将它们都用作值,然后将值放入数据构造函数中:
let x = Just 3
let y = Nothing
您还可以使用模式匹配将值移出具有数据构造函数的值:
case x of
Just y -> putStr y
Nothing -> putStr "Nothing here to see"
箭头本身没有任何特殊含义。当模式匹配Just y
或Nothing
时,它仅将模式(如case
或putStr y
与putStr "Nothing here to see"
表达式的值分开。这只是语法。
答案 1 :(得分:3)
->
仅表示替代项和在单个case
子句中返回的结果值之间的对应关系。
x = 2
y = case x of
2 -> 4
5 -> 42
_ -> 0
将y
设置为4。
Left
和Right
是Either
的数据构造函数:
data Either t u = Left t | Right u