[英]Understanding how haskell applicative functors are applied
我只是對應用函子有一個簡單的問題,以幫助我掌握它們。 這只是我在ghci中申請的東西。
[(+3),((-) 3),(*3)] <*> [4]
[7,-1,12]
這對我來說很有意義。 基本應用。 但是當嘗試:
[(Just (+3)),(Just ((-) 3)),(Just (*3))] <*> [Just 4]
我收到了很多錯誤。 我對原因有所了解。 有兩個數據構造函數( []
和Maybe
),而<*>
函數僅“剝離”其中一個。 我想幫助我理解的是haskell到底要逐步嘗試直到失敗,以及如何解決它並成功地將其計算為:
[(Just 7),(Just -1),(Just 12)]
您有兩個不同的Applicative
實例。 的確
Just (* 3) <*> Just 4 == Just 12
但[]
實例只是試圖在第一個列表應用的每個“功能”在第二的每個值,所以你最終想申請
(Just (* 3)) (Just 4)
這是一個錯誤。
(更准確地說,您的Just
值列表具有錯誤的類型以用作<*>
的第一個參數。)
相反,您需要在第一個列表上映射<*>
。
> (<*>) <$> [(Just (+3)),(Just ((-) 3)),(Just (*3))] <*> [Just 4]
[Just 7,Just (-1),Just 12]
(將高階函數映射到列表上通常是您通常首先獲取已包裝函數列表的方式。例如,
> :t [(+3), ((-) 3), (* 3)]
[(+3), ((-) 3), (* 3)] :: Num a => [a -> a]
> :t Just <$> [(+3), ((-) 3), (* 3)]
Just <$> [(+3), ((-) 3), (* 3)] :: Num a => [Maybe (a -> a)]
)
Data.Functor.Compose
提到的Data.Functor.Compose
是另一種選擇。
> import Data.Functor.Compose
> :t Compose [(Just (+3)),(Just ((-) 3)),(Just (*3))]
Compose [(Just (+3)),(Just ((-) 3)),(Just (*3))]
:: Num a => Compose [] Maybe (a -> a)
> Compose [(Just (+3)),(Just ((-) 3)),(Just (*3))] <*> Compose [Just 4]
Compose [Just 12,Just (-1),Just 12]
> getCompose <$> Compose [(Just (+3)),(Just ((-) 3)),(Just (*3))] <*> Compose [Just 4]
[Just 12,Just (-1),Just 12]
Compose
的定義非常簡單:
newtype Compose f g a = Compose { getCompose: f (g a) }
神奇的是,只要f
和g
都是(應用的)仿函數,那么Compose fg
也是 (應用的)仿函數。
instance (Functor f, Functor g) => Functor (Compose f g) where
fmap f (Compose x) = Compose (fmap (fmap f) x)
instance (Applicative f, Applicative g) => Applicative (Compose f g) where
pure x = Compose (pure (pure x))
Compose f <*> Compose x = Compose ((<*>) <$> f <*> x)
在Applicative
實例中,您可以看到與我上面使用的(<*>) <$> ...
相同的用法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.