簡體   English   中英

monoid 和 applicative 是如何聯系起來的?

[英]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 中ApplicativeFunctor之間的區別,因為對於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.

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