簡體   English   中英

`(>>=)` 可以重新聲明為 `(a -> mb) -> ma -> mb` 嗎?

[英]Can `(>>=)` be redeclared as `(a -> m b) -> m a -> m b`?

在 Haskell Monad中聲明為

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

我想知道是否可以將綁定運算符重新聲明為

(>>=)   ::  (a  ->  m   b)  ->  m   a   ->  m   b

?

第二個聲明更清楚地表明(>>=)將 a a -> mb類型的函數映射到ma -> mb類型的函數,而原始聲明不太清楚它的含義是否正確?

聲明的更改會使某些事情從可能變為不可能,還是只需要對使用 monad 進行一些更改(這對 Haskell 程序員來說似乎是可以忍受的)?

謝謝。

>>=在實踐中往往比它的翻轉對應物=<<更有用的原因之一是:它與 lambda 符號配合得很好。 即, \\充當語法先驅,因此您可以繼續計算而無需任何括號。 例如,

 do x <- [1..5]
    y <- [10..20]
    return $ x*y

可以很容易地用>>=重寫為

   [1..5] >>= \x -> [10..20] >>= \y -> return $ x*y

您仍然擁有與do版本大致相同的“命令式流程”感覺。

而使用=<<則需要使用笨拙的括號,而且似乎會倒着讀:

   (\x -> (\y -> return $ x*y) =<< [10..20]) =<< [1..5]

好吧,你可能會說這感覺更像是函數應用程序。 但是在這有用的地方,只使用applicative functor接口而不是 monadic 接口通常更令人心酸:

  (\x y -> x*y) <$> [1..5] <*> [10..20]

或短

  (*) <$> [1..5] <*> [10..20]

請注意, (<*>) :: f (a->b) -> fa -> fb基本上具有您建議的=<<順序,只是a->位於函子內部而不是外部。

暫無
暫無

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

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