Haskell “(>;=)”是否可以重新声明为“(a->;m b)——>;并购->;m b`?

Haskell “(>;=)”是否可以重新声明为“(a->;m b)——>;并购->;m b`?,haskell,monads,Haskell,Monads,在HaskellMonad中声明为 class Applicative m => Monad m where return :: a -> m a (>>=) :: m a -> (a -> m b) -> m b return = pure 我想知道是否可以将bind操作符重新声明为 (>>=) :: (a -> m b)

在Haskell
Monad
中声明为

class   Applicative m   =>  Monad   m   where
    return  ::  a   ->  m   a
    (>>=)   ::  m   a   ->  (a  ->  m   b)  ->  m   b
    return  =   pure
我想知道是否可以将bind操作符重新声明为

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

第二个声明使
(>>=)
a->mb
类型的函数映射为
ma->mb
类型的函数,而原始声明不太清楚它的含义,这对吗

声明的改变会使事情从可能变为不可能,还是仅仅需要对monad的使用进行一些改变(Haskell程序员似乎可以接受)


谢谢。

有一个原因使得
>=
在实践中比它的翻转对应物更有用:它可以很好地使用lambda符号。也就是说,
\
充当语法先驱,因此您可以在不需要任何括号的情况下继续计算。比如说,

 do x <- [1..5]
    y <- [10..20]
    return $ x*y
您仍然有与
do
版本大致相同的“命令流”感觉

而对于
=预编码(\x-(\y->return$x*y)=b)->fa->fb
基本上具有翻转版本的
=No顺序。这被实现为
(=谢谢。你对什么说“不”?第二个声明清楚地表明(>>=)是正确的吗将a->m b类型的函数映射为m a->m b类型的函数,而原始声明不太清楚它的含义?声明的更改会使某些事情从可能变为不可能,还是只需要对monad的使用进行一些更改(Haskell程序员似乎可以接受)?这实际上是一个值得讨论的有趣话题,
>=
的类型签名,正如您所指出的,“向后”我认为@leftaroundabout的回答很好地回答了为什么Haskell选择按顺序定义参数,但最终这是相当武断的,而且是一个意见问题。我不清楚你的问题到底是什么是。声明的顺序旨在促进Kleisli箭头从左到右的链接,而不是建议任何特定的映射。给定两个这样的箭头
f::a->mb
g::b->mc
,您可以编写
hx=x>=f>>=g
。从左到右的“合成”考虑到使用单子表示顺序计算,被认为更自然。明确回答你的第二个问题:它只是
翻转(>>=)
,也被定义为
(=谢谢。我的第二个声明清楚地表明(>>=)是正确的吗将a->m b类型的函数映射为m a->m b类型的函数,而原始声明不太清楚它的含义?我不知道。也许。它没有使它更清楚;它使它成为真的。原始声明没有将
a->m b
类型的函数映射为
m a->m b
类型的函数;它将值映射为f type
ma
到类型为
(a->mb)->mb
的函数。但是
>=
的目的不是将事物映射到“链接”计算;
x>=f
的输出是一个适合左参数到另一个调用
=
x>=f>=g>=…
   [1..5] >>= \x -> [10..20] >>= \y -> return $ x*y
   (\x -> (\y -> return $ x*y) =<< [10..20]) =<< [1..5]
  (\x y -> x*y) <$> [1..5] <*> [10..20]
  (*) <$> [1..5] <*> [10..20]