2015-10-16 64 views
1

在Haskell的單子,我可以很容易地定義操作(>=>)爲:定義單子運營商

(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> a -> m c 
f >=> g = \x -> f x >>= g 

我也知道,(>>=)可以使用(>=>)表示:讓我們把(>>=)(..)

(..) :: Monad m => m a -> (a -> m b) -> m b 
m .. k = m >=> \_ -> k 

然而有些事情是不正確的......有人能指出什麼嗎?

+1

這可能只是一個複製粘貼的錯誤,但是您爲'(>> =)'使用了'(> =>)'簽名。 – duplode

+0

@duplode難道這不正確嗎?我爲'(>> =)'創建一個別名爲'(..)',所以我想應用'(> =>)'操作符來定義'(..)'...有意義嗎? – cybertextron

+0

它是有道理的;在你寫的問題中,'(>> =)'是'Monad m => ma - >(a - > mb) - > mb',類型是'(..):: Monad m = >(a→mb)→(b→mc)→(a→mc)。 – duplode

回答

9

使用常數函數(即\_ -> -- etc.)將函數作爲非函數參數的想法,因此您可以將函數傳遞給(>=>)的想法是完全正確的。只有兩個問題。首先,你是做給了錯誤的說法,因爲一個是不是一個功能是m

GHCi> :t \m k -> (\_ -> m) >=> k 
\m k -> (\_ -> m) >=> k :: Monad m => m b -> (b -> m c) -> a -> m c 

其次,(>=>)給你(在正上方的演示a -> m c類型)的功能。您必須將其應用於某些內容才能獲得與(>>=)匹配的結果類型。由於這樣的說法是不相關的(你最終將其送入一個常數函數),你可以只使用()

GHCi> :t \m k -> ((\_ -> m) >=> k)() 
\m k -> ((\_ -> m) >=> k)() :: Monad m => m b -> (b -> m c) -> m c 

就是這樣。我覺得稍微漂亮使用const功能,而不是寫\_ ->,所以我會寫:

​​
+3

如果選擇'()'特別適合,通過用'\() - > m'替換'const m'可以更清楚地說明原因。 – dfeuer

2

的解決方案如下:

(..) :: Monad m => m a -> (a -> m b) -> m b 
m .. k = 
    (const m >=> k) undefined 

使用const我們提升的操作m awhatever -> m a。這個提升的版本並沒有給出一個該死的,我們傳遞給它的,所以它可能是undefined

+5

我把它換成另一種方式:所以它可能不是*未定義。 duplode選擇'()'似乎非常合理。實際上,'()'具有特殊意義,因爲'( - >)()'可以被讀爲「point」。 – dfeuer

+0

其實我同意。 –