了解涉及Left,Right和case语句的示例

时间:2018-08-15 14:41:00

标签: haskell

我正在读《学习哈斯凯尔》,这本书使我感到困惑,其中一个例子使我感到困惑,您可以看到例子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的特定行使我感到困惑。首先,我想知道箭头的确切含义(我可以想象它的含义,但是我想要更多的“学术”内容)

另一部分是单词LeftRight,我不知道他们是否像map那样使用它,起初看起来像一个函数,但它只是一个变量名,或者用作代码。在那种情况下,他们真正做什么?

更新

我发现here对“任一”都有很好的解释。我将其放在此处作为对我有同样疑问的任何人的参考(请转到“也许比可能更好”)。我将摘录一段文字,为我提供所需的最终线索,以防日后该页面消失。

“谈论错误处理'也许'有点局限。我们对失败的了解仅是它发生了。实际上,我们想了解更多。因此,错误处理的下一步是使用'要么。

这两种参数中的任何一种都不是。 Either类型的值包含a类型或b类型的值。我们可以通过在任一构造函数上进行模式匹配来区分这两种可能性。这两种方法都可以用作Maybe的概括,其中Left不仅编码失败,还伴随错误消息。正确编码成功及其伴随的价值。”

2 个答案:

答案 0 :(得分:4)

标识符NothingJustMaybe类型的数据构造函数,其给出方式为:

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 yNothing时,它仅将模式(如caseputStr yputStr "Nothing here to see"表达式的值分开。这只是语法。

答案 1 :(得分:3)

->仅表示替代项和在单个case子句中返回的结果值之间的对应关系。

x = 2
y = case x of
    2 -> 4
    5 -> 42
    _ -> 0

y设置为4。

LeftRightEither的数据构造函数:

data Either t u = Left t | Right u