2015-09-01 29 views
7

在單子以下實例:無法理解單子( - >)

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

這是迫使k是兩個參數的函數?如果是這樣,你爲什麼要通過(f r) AND rk

+0

您可能會喜歡閱讀器monad上的[Monads as Containers](https://wiki.haskell.org/Monads_as_containers)部分(搜索「reader」)。 –

+0

是'k'是函數'a→r→b'。 'r'是'r'的唯一實例,'f''是獲得'a'的唯一方法,所以你沒有多少選擇。 – Lee

+0

[如何使用( - >)Monad實例以及有關( - >)混淆的可能的重複](http://stackoverflow.com/questions/5310203/how-to-use-instances-of-monad-and-混亂,約) – Cactus

回答

9

這是強迫k是兩個參數的函數嗎?

是。綜觀Monad的定義,我們有

class Monad m where 
    return :: a -> m a 
    (>>=) :: m a -> (a -> m b) -> m b 

(->) rm,我們有

return :: a -> (->) r a 
(>>=) :: (->) r a -> (a -> (->) r b) -> (->) r b 

現在,(->) r a僅僅是r -> a一個奇怪的語法,以及類似的其他情況,所以我們得到

return :: a -> r -> a 
(>>=) :: (r -> a) -> (a -> r -> b) -> r -> b 

所以我們可以看到第二個參數>>=必須是(至少)兩個參數的函數。

爲什麼?因爲兩個參數的函數只是一個函數帶一個參數並返回一個參數的函數,而>>=的第二個參數應該是一個函數帶一個參數並返回monad的類型構造函數的值;對於函數monad,這個值將是一個函數。因此>>=的第二個參數將是兩個參數的函數。

[W] hy你想通過(f r)AND r到k?

部分是因爲它使得(->) r類型適合Monad的統一結構,這對於許多原因很有用。

部分k不知道您正在使用哪個功能f。這意味着,從k的角度來看,f rr這兩個參數確實是獨立的--- k不能從另一個計算出來。

考慮一下這個功能:

-- | 'f' takes two numbers and adds them together 
f :: (->) (Int, Int) Int 
f = fst >>= \ n0 -> snd >>= \ n1 -> return (n0 + n1) 

功能\ n0 -> snd >>= \ n1 -> return (n0 + n1)並不關心這裏的說法從何而來,或特別是它的參數是輸入的第一個組件。所以它需要參數n0和完整的輸入。