Sau*_*nda 2 haskell haskell-lens
如果我有一个嵌套记录的镜头,每个镜头返回一个Maybe,我怎么能让它们组成,所以如果"遍历"中的任何内容返回一个Nothing最后的结果是Nothing?
data Client = Client
{
clientProperties :: Maybe Properties
, ...
}
data Properties = Properties
{
propSmtpConfig :: Maybe SmtpConfig
, ...
}
c :: Client
c = undefined
smtp = c ^. (properties . smtpConfig) -- How to make these lenses compose?
Run Code Online (Sandbox Code Playgroud)
编辑我尝试了很多选项,但这是我能想到的最好的选择.寻找更清洁的东西:
(client ^. properties) >>= (view smtpConfig)
Run Code Online (Sandbox Code Playgroud)
你可以使用_Just棱镜.这是一个人为的例子:
> (Just (Just 1, ()), ()) & _1 . _Just . _1 . _Just +~ 1
(Just (Just 2,()),())
Run Code Online (Sandbox Code Playgroud)
在你的情况下,我想你想要
properties . _Just . smtpConfig . _Just
Run Code Online (Sandbox Code Playgroud)
client ^? properties . _Just . smtpConfig . _Just
Run Code Online (Sandbox Code Playgroud)
编辑:像镜头这样的光学器件可以将小动作变成大动作。光学合成是函数合成。_Just将 上的动作 变为a上的动作Maybe a。镜头可以将小的读取动作变成大的读取动作,将小的写入动作变成大的写入动作,但_Just无法处理读取动作,因为在a中Nothing没有a。因此,_Just它是比透镜弱的光学器件,即遍历。组合光学器件始终可以准确地执行所有部件都可以执行的操作。因此properties . _Just . smtpConfig . _Just是一个遍历。(^?)使用遍历可以使用的读取操作的变体:“也许读取一个值”。因此上面这行代码将微不足道的成功阅读动作变成Just :: SmtpConfig -> Maybe SmtpConfig了大型阅读动作Client -> Maybe SmtpConfig。