[英]Monadic alteration to tuple
我正在尋找類似於以下類型的函數:
Monad m => (a, b) -> (b -> m c) -> m (a, c)
在我看來,它是綁定( >>=
)和鏡頭操作的某種組合。
我知道我可以在綁定后用模式匹配來解決這個問題,但我的直覺告訴我,通過利用鏡頭來編寫這個“更簡單”的方法。
有沒有這樣的手術?
這絕對是鏡頭。 monad實際上只是一點點分心,因為你需要的只是一個仿函數:
changesecond (a, b) f = fmap (a,) (f b)
我很確定_2
鏡頭可以用一個基本的鏡頭來做你的競標,但可能over
但我還不太熟悉這個庫。
實際上不需要組合器。 你可以寫
changesecond pair f = _2 f pair
您應該能夠從Lens
類型的一般定義中解決這個問題。
這個簡單的例子展示了Van Laarhoven鏡頭結構的主題:
fmap
將上下文恢復為結果。 Ed Kmett的lens
庫以各種方式闡述了這個主題。 有時它會加強仿函數約束。 有時它會將函數概括為profunctor。 在Equality
的情況下,它刪除了仿函數約束。 事實證明,相同的基本類型形狀可以表達許多不同的想法。
如果你將Monad
約束放寬到Applicative
,你的函數只是forM = flip mapM
,或for = flip traverse
。 遍歷的Functor
是(,) a
。
Prelude> let foo :: Applicative f => (a, b) -> (b -> f c) -> f (a, c); foo p k = traverse k p
Prelude> :t foo
foo :: Applicative f => (a, b) -> (b -> f c) -> f (a, c)
Prelude> foo (1,2) (\x -> [x,2*x])
[(1,2),(1,4)]
(另外,正如dfeuer指出的那樣,在這種特殊情況下你甚至不需要Applicative
。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.