簡體   English   中英

如何組合兩個組合的應用函子?

[英]How to combine two composed applicative functors?

我有兩個組合的應用函子Maybe [Integer]並想將它們與<$> / <*>結合,但我堅持應用應用操作。 以下內容不進行類型檢查:

(<*>) (<*>) ((<$>) ((+) <$>) $ Just [1,2,3]) $ Just [4,5,6]

預期結果:

Just [5,6,7,6,7,8,7,8,9]

仿函數部分起作用,即作為第一個參數傳遞給<*>的中間值是Just [Integer -> Integer] 我習慣了 S 表達式,所以我很難使用 Haskell 語法。 我知道Compose ,但我只對沒有抽象的組合感興趣。

正如夏立耀所說,使用liftA2可以減少混亂。

但是,如果您仍然想看看它在底層操作方面會變成什么,我們可以擴展liftA2的定義:

liftA2 :: (a -> b -> c) -> f a -> f b -> f c
liftA2 f x y = f <$> x <*> y

所以解決方案變成

(liftA2 . liftA2) (+) (Just [1,2,3]) (Just [4,5,6])
= liftA2 (liftA2 (+)) (Just [1,2,3]) (Just [4,5,6])
= (\f x y -> f <$> x <*> y) ((\f x y -> f <$> x <*> y) (+)) (Just [1,2,3]) (Just [4,5,6])
= ((\f x y -> f <$> x <*> y) (+)) <$> Just [1,2,3] <*> Just [4,5,6]
= (\x y ->  (+) <$> x <*> y) <$> Just [1,2,3] <*> Just [4,5,6]

現在,這不像上面的示例那樣采用無點樣式,我真的認為將其轉換為無點有幫助,但這是來自http://pointfree.ZF98ED07A4D5F50F7DEFZ1410D 的 output

((<*>) . ((+) <$>)) <$> Just [1, 2, 3] <*> Just [4, 5, 6]

我們可以通過 eta-expanding 看到這是相同的:

(<*>) . ((+) <$>)
= \x y -> ((<*>) . ((+) <$>)) x y
= \x y -> ((<*>) $ ((+) <$>) x) y
= \x y -> ((<*>) ((+) <$> x)) y
= \x y -> (<*>) ((+) <$> x) y
= \x y -> ((+) <$> x) <*> y
= \x y -> (+) <$> x <*> y

liftA2可能比(<*>)更容易混淆。

(+) :: Int -> Int -> Int
liftA2 (+) :: [Int] -> [Int] -> [Int]
liftA2 (liftA2 (+)) :: Maybe [Int] -> Maybe [Int] -> Maybe [Int]

liftA2 (liftA2 (+)) (Just [1,2,3]) (Just [4,5,6])

兩個Applicative的組合始終是一個Applicative (與Monad的情況不同)。

我們可以在這里使用newtypeCompose Data.Functor.Compose來發揮我們的優勢:

newtype Compose f g a = Compose { getCompose :: f (g a) }

它需要一些包裝,但這種解決方案在適當的情況下可能很有用:

example :: Maybe [Int]
example =
  getCompose ((+) <$> Compose (Just [1,2,3]) <*> Compose (Just [4,5,6]))

另一種方法是使用ListT轉換器 雖然在這種情況下它工作得很好,但由於某種原因,它是一個折舊的轉換器,用紅色標記為"Deprecated: This transformer is invalid on most monads"

import Control.Monad.Trans.List

doit :: (Int-> Int -> Int) -> Maybe [Int] -> Maybe [Int] -> Maybe [Int]
doit f mt1 mt2 = runListT $ f <$> (ListT mt1) <*> (ListT mt2)

λ> doit (+) (Just [1,2,3]) (Just [4,5,6])
Just [5,6,7,6,7,8,7,8,9]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM