簡體   English   中英

非單子函數的綁定運算符

[英]Bind operator for non-monadic functions

我或多或少地把頭繞在單子上,但我無法推斷出表達方式

(>>=) id (+) 3

計算結果為 6。似乎表達式以某種方式簡化為

(+) 3 3

但如何? 3如何應用兩次? 有人可以解釋幕后發生的事情嗎?

這遵循如何為((->) r)類型定義>>=

(f =<< g) x  =  f (g x) x

因此

(>>=) id (+) 3
=
(id >>= (+)) 3
=
((+) =<< id) 3
=
(+) (id 3) 3
=
3 + 3

查看類型:

> :t let (f =<< g) x = f (g x) x in (=<<)
let (f =<< g) x = f (g x) x in (=<<)
        :: (t1 -> (t2 -> t)) -> (t2 -> t1) -> (t2 -> t)

> :t (=<<)
(=<<) :: Monad m => (a -> m b) -> m a -> m b

類型匹配

t1 ~ a
(t2 ->) ~ m    -- this is actually ((->) t2)`
t ~ b

因此,這里的約束Monad m表示Monad ((->) t2) ,它定義了=<<>>=的定義,它們會被使用。

如果你想從類型推導出定義,

(>>=) :: Monad m => m a -> (a -> m b) -> m b
m ~ ((->) r)

(>>=) :: (r -> a) -> (a -> r -> b) -> (r -> b)
(>>=)    f            g                r =  b
  where
  a  = f r
  rb = g a
  b  = rb r

簡化后成為我們上面使用的那個。

如果你想“用文字”來理解它,

(=<<) :: (Monad m, m ~ ((->) r)) => (a -> m b) -> m a -> m b
(f =<< g) x  =  f (g x) x
  • g是“可以計算”“ a ”的“一元值”,表示為r -> a
  • fa計算“可以計算”a“ b ”的“一元值”,表示為r -> b
  • 因此\x -> f (gx) x是一個“可以計算”a“ b ”的一元值,給定一個“ r ”。

所以這些“非單子函數”實際上是單子值,它們恰好是函數。

因此,在您的示例中, g = idf = (+)

  • id是一個“一元值”,“可以計算”一個“ a ”,一個a -> a
  • (+) a計算一個“可以計算” a“ b ”的“一元值”,一個a -> b ,其中b實際上也是一個a
  • 因此\x -> (+) (id x) x是一個“可以計算”一個“ a ”的一元值,給定一個“ a ”:
(>>=) id (+)
=
((+) =<< id) 
=
\x -> (+) (id x) x
=
\x -> (+)     x  x

為威爾的出色回答增添了一些色彩。

如果我們查看source ,我們有這個:

 instance Monad ((->) r) where f >>= k = \ r -> k (fr) r

如果我們稍微重新排列輸入表達式,我們會得到(id >>= (+)) 3 這現在類似於上面顯示的形式。 現在將輸入擬合到上述“模板”中,我們可以將輸入重寫為\ r -> (+) (id r) r

這與我們為最終評估得出的表達式相同,即(+) (id 3) 3

暫無
暫無

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

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