【发布时间】:2021-11-02 21:47:05
【问题描述】:
我希望获得一些有助于理解 Monad Transformers 的信息,以及与此相关的使用 do 表示法会发生什么。我试图理解的示例如下:
data ProtectedData a = ProtectedData String a
accessData :: String -> ProtectedData a -> Maybe a
accessData s (ProtectedData pass v) =
if s == pass then Just v else Nothing
type Protected s a = MaybeT (Reader (ProtectedData s)) a
-- untangles the monad construction
run :: ProtectedData s -> Protected s a -> Maybe a
run ps psa = runReader (runMaybeT psa) ps
access :: String -> Protected a a
access pass = do
-- ask :: ReaderT (ProtectedData a) Identity (ProtectedData a)
-- lift :: ... -> MaybeT (ReaderT (ProtectedData a) Identity) (ProtectedData a)
pd <- lift ask
-- as i understand it: ask returns the value inside the thing.
-- the left arrow actually applies the monad
let v = accessData pass pd
-- return :: Maybe a -> Reader (ProtectedData a) (Maybe a)
MaybeT $ return v
据我了解,Protected 类型描述了一些 受保护 数据,这些数据存储在共享环境 (Reader) 中,属于 Maybe (MaybeT) 类型。
我在使用类型变量 s 和 a 时遇到问题:
-
s是否描述受保护数据的字符串(密码),a受保护数据的类型? -
s是否描述了受保护数据的类型,如果是,是什么a描述?
在函数中运行:
run :: ProtectedData s -> Protected s a -> Maybe a
run ps psa = runReader (runMaybeT psa) ps
据我了解,Protected 内部的Reader 在ProtectedData 上运行,以返回值。
这里只剩下函数access:
access :: String -> Protected a a
access pass = do
pd <- lift ask
let v = accessData pass pd
MaybeT $ return v
哪个是最让我头疼的。首先,我在掌握效果和结果方面存在问题。
- 这个函数是用来向
Reader注入密码和数据的吗? - 是否用于访问数据,如果输入错误密码失败?
其次,我无法理解第一行
pd <- lift ask
- 我了解,
ask用于访问共享环境 通过Reader,但是为什么我要lift它到MaybeT才能得到 里面的实际值?
【问题讨论】:
标签: haskell functional-programming monads monad-transformers