2017-06-19 4 views
1

各レンズが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? 

編集私は多くのオプションを試してみましたが、これは、私が思い付くことが最高です。何か清掃を探しています:

(client ^. properties) >>= (view smtpConfig) 
+1

ですね.html#v:_Just)。 –

+0

ありがとう@Gurkenglas。これを回答として提出してください。これはまさに私が必要としていたものです。 –

答えて

1
client ^? properties . _Just . smtpConfig . _Just 
5

_Just prismを使用できます。ここでは不自然な例です:あなたのケースでは

> (Just (Just 1,()),()) & _1 . _Just . _1 . _Just +~ 1 
(Just (Just 2,()),()) 

、私はあなたが

properties . _Just . smtpConfig . _Just 
+0

'_Just'レンズは' fromJust'のように振る舞います。つまり、値が 'Nothing'ならばエラーになりますか? –

+0

これは機能しません。 –

+0

@SaurabhNanda例外はありません。それは単に値を設定しません。 – Reactormonk

1

traverseをしたいと思います覚えて、有効Traversalです。

getSmtpConfig :: Traversal' Client SmtpConfig 
getSmtpConfig = properties . traverse . smtpConfig . traverse 

Traversalは、あなたがここにできる最善である - がないかもしれないので、SmtpConfig - あなたがLensを取得することはできません。

あなたがthe _Just prismを使用したいかのように、このコードは実際には同じTraversalを生成しますが、それはおそらくです(LensTraversal「がゼロまたは多くがあるかもしれない」と言う一方で、「これらの事のちょうど1が常にあります」と言います)あなたがまだプリズムに挑戦していなければ、少し理解しやすくなります。

Traversalは結果が見つからない可能性がありますので、^.を使用して1つの結果にアクセスすることはできません。 「安全な頭」の演算子^?(別名flip preview)を使用する必要があります。あなたは[ `_Just`プリズム](https://hackage.haskell.org/package/lens-4.15.3/docs/Control-Lens-Prismを探している可能性がありよう

smtp :: Maybe SmtpConfig 
smtp = c^?properties.traverse.smtpConfig.traverse 
関連する問題