[英]Applicative functors as monoidal functors
正如Hackage for Applicative Functors中所提到的,它們是強大的松散幺半體仿函數。 那么為什么他們在Haskell中的定義不是這樣表達的呢:
class Functor f => MonoidalApplicative f where
mult :: f a -> f b -> f (a,b)
unit :: a -> f a
starAp :: f (a -> b) -> f a -> f b
starAp h x = fmap (uncurry ($)) (mult h x)
<*>
(starAp)在乘法方面很容易重建,這個定義看起來更簡單。 例如,這是Maybe實例:
instance MonoidalApplicative Maybe where
mult (Just x) (Just y) = Just (x,y)
mult _ _ = Nothing
unit x = Just x
正如你在回答的評論中提到的那樣, join
和>>=
有類似的故事。 當有幾種語義等價的方法來定義某些東西時,最好總是選擇最有效和務實的方式。 Haskell旨在編寫代碼,而不是為了證明事物(盡管如此,不幸的是Haskell仍然不會成為非常流行的編程語言)。
如果starAp
有默認實現,幾乎沒有人會實現它(正如現在發生在Monad
類型類中的>>
)。 但<*>
是非常有用的操作。 它用於應用程序和megaparsec
解析器很多( megaparsec
, attoparsec
, optparse-applicative
),我無法想象我的生活沒有liftA*
加入事物。 並且這項操作盡可能高效非常重要。 實施starAp
為fmap (uncurry ($)) (mult hx)
可能帶來的困難時期內聯和優化的東西編譯器。
此外,表示Applicative
使用mult
和unit
業務並沒有真正解決任何問題。 顯然, mult = liftA2 (,)
。 但你的實施
mult (Just x) (Just y) = Just (x,y)
不完全正確。 因為你的實現不夠懶惰。 您將評估這兩種情況,只需評估一種情況就足夠了。 所以即使使用這個簡單的功能你仍然會陷入困境。 因此,這種表示嚴格地更糟。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.