在研究Haskell的类型系统时,我遇到了称为"的构造函数。一个用例是下面的代码
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 number "
++ show lockerNumber ++ " doesn't exist!"
Just (state, code) -> if state /= Taken
then Right code
else Left $ "Locker " ++ show lockerNumber
++ " is already taken!"
lockers :: LockerMap
lockers = Map.fromList
[(100,(Taken,"ZD39I"))
,(101,(Free,"JAH3I"))
,(103,(Free,"IQSA9"))
,(105,(Free,"QOTSA"))
,(109,(Taken,"893JJ"))
,(110,(Taken,"99292"))
]
使用示例函数调用:
> lockerLookup 101 lockers
我想知道为什么不删除Left
和Right
值构造函数。该代码仍然可以正常工作,同时仍能打印出我们想要的值。
Either
是标记的联合 [Wiki]。这意味着它可以从(在这种情况下(获得两种类型的值。如果Code
为不是字符串,则您的函数将需要某种总和类型。否则它将如何传达Code
或String
?因此,Either
在列表中使用,该列表中可以包含Int
S和String
S:[Either Int String]
。
Either
经常用于封装可能失败的计算。然后,Left
构造函数存储错误消息/异常参数,而Right
数据构造函数存储成功计算的结果。
此逻辑是在instance Monad Either
[SRC]中编码的,确实是:
instance Monad (Either e) where Left l >>= _ = Left l Right r >>= k = k r
因此,在这里我们可以定义一个计算:
some_computation :: Val1 -> Either Err Val4
some_computation v1 = do
v2 <- some_computation_that_can_fail1 v1
v3 <- some_computation_that_can_fail1 v2
some_computation_that_can_fail v2 v3
在这个假设的示例中,这些功能具有some_computation_that_can_fail1 :: Val1 -> Either Err Val2
类型,some_computation_that_can_fail2 :: Val2 -> Either Err Val3
和some_computation_that_can_fail1 :: Val2 -> Val3 -> Either Err Val4
。
在这里some_computation_that_can_fail1 v1
返回Left err
,则some_computation v1
将返回该Left err
。另一方面,如果它返回Right result
,则v2
将访问该结果,因此您可以在some_computation_that_can_fail2 v2
中进一步处理result
,等等。