[英]How are monoid and applicative connected?
我正在閱讀有關應用程序的haskellbook並試圖理解它。
在書中,作者提到:
因此,有了 Applicative,我們有一個 Monoid 用於我們的結構和函數應用程序,用於我們的值!
幺半群如何連接到應用程序?
備注:我還沒有這本書,IIRC,至少有一位作者在 SO 上很活躍,應該能夠回答這個問題。 話雖這么說,幺半群(或者更確切地說是半群)背后的想法是你有辦法從那個幺半群1中的兩個對象創建另一個對象:
mappend :: Monoid m => m -> m -> m
那么Applicative
是怎樣的一個幺半群呢? 好吧,正如您的引述所說,就其結構而言,它是一個幺半群。 也就是說,我們從一個f something
開始,繼續f anotherthing
,然后我們得到,你已經猜到了它是一個f resulthing
:
amappend :: f (a -> b) -> f a -> f b
在我們繼續之前,在很短的時間內,讓我們忘記f
有種類* -> *
。 我們最終會得到什么?
amappend :: f -> f -> f
那是“單軸結構”部分。 這就是 Haskell 中Applicative
和Functor
之間的區別,因為對於Functor
我們沒有那個屬性:
fmap :: (a -> b) -> f a -> f b
-- ^
-- no f here
這也是如果我們嘗試將(+)
或其他函數與fmap
一起使用時我們會遇到麻煩的原因:在單個fmap
之后我們被卡住了,除非我們能以某種方式在那個新結構中應用我們的新函數。 這就把我們帶到了你問題的第二部分:
因此,通過 Applicative,我們有 [...] 函數應用程序來實現我們的價值!
函數應用是($)
。 如果我們看一下<*>
,我們可以立即看出它們是相似的:
($) :: (a -> b) -> a -> b
(<*>) :: f (a -> b) -> f a -> f b
如果我們忘記了(<*>)
中的f
,我們只會以($)
結尾。 所以(<*>)
只是我們結構上下文中的函數應用程序:
increase :: Int -> Int
increase x = x + 1
five :: Int
five = 5
increaseA :: Applicative f => f (Int -> Int)
increaseA = pure increase
fiveA :: Applicative f => f Int
fiveA = pure 5
normalIncrease = increase $ five
applicativeIncrease = increaseA <*> fiveA
我猜,這就是作者所說的“函數應用”的意思。 我們突然可以將隱藏在我們結構中的那些函數應用到我們結構中的其他值上。 由於單調的性質,我們留在那個結構中。
話雖如此,我個人永遠不會稱其為 monodial,因為<*>
不會對同一類型的兩個參數進行操作,並且應用程序缺少空元素。
1對於真正的半群/幺半群,該操作應該是關聯的,但這在這里並不重要
雖然這個問題很久以前就得到了很好的回答,但我想補充一點。
看看下面的課程:
class Functor f => Monoidal f where
unit :: f ()
(**) :: f a -> f b -> f (a, b)
在解釋為什么我們需要一些Monoidal
類來解決有關Applicative
s 的問題之前,讓我們先看看它的規律,遵守它給我們一個幺半群:
fa
( x
) 同構於f ((), a)
( unit ** x
),這給了我們左恆等式。 (** unit):: fa -> f ((), a)
, fmap snd:: f ((), a) -> fa
。fa
( x
) 也是同構f (a, ())
( x ** unit
),這給了我們正確的恆等式。 (unit **):: fa -> f (a, ())
, fmap fst:: f (a, ()) -> fa
。f ((a, b), c)
( (x ** y) ** z
) 同構於f (a, (b, c))
( x ** (y ** z)
),這給了我們結合性。 fmap assoc:: f ((a, b), c) -> f (a, (b, c))
, fmap assoc':: f (a, (b, c)) -> f ((a, b), c)
。 您可能已經猜到了,可以用Monoidal
寫下Applicative
的方法,反之亦然:
unit = pure ()
f ** g = (,) <$> f <*> g = liftA2 (,) f g
pure x = const x <$> unit
f <*> g = uncurry id <$> (f ** g)
liftA2 f x y = uncurry f <$> (x ** y)
此外,可以證明Monoidal
半群律和Applicative
律告訴我們的是同一件事。 我剛才問了一個關於這個的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.