6

教程中,我发现了以下代码段:

deposit :: (Num a) => a -> a -> Maybe a
deposit value account = Just (account + value)

withdraw :: (Num a,Ord a) => a -> a -> Maybe a
withdraw value account = if (account < value) 
                         then Nothing 
                         else Just (account - value)

eligible :: (Num a, Ord a) => a -> Maybe Bool
eligible account =
  deposit 100 account >>=
  withdraw 200 >>=
  deposit 100  >>=
  withdraw 300 >>=
  deposit 1000 >>
  return True

main = do
  print $ eligible 300 -- Just True
  print $ eligible 299 -- Nothing

我无法弄清楚该>>=功能应该如何工作。起初它接受一个Maybe a值作为它的第一个参数:deposit 100 account >>=

之后,它似乎将a -> Maybe a其作为第一个参数:withdraw 200 >>=编译器如何批准?不应该>>=总是Maybe a作为它的第一个参数吗?

一个可能的解决方案是,如果>>=函数的优先级按以下方式工作:((a >>= b) >>= c) >>= d

但据我所知,情况恰恰相反:a >>= (b >>= (c >>= d))

4

1 回答 1

14

据我所知,情况正好相反:a >>= (b >>= (c >>= d))

不。

GHCi> :i >>=
class Monad m where
  (>>=) :: m a -> (a -> m b) -> m b
  ...
    -- Defined in `GHC.Base'
infixl 1 >>=

infixl意味着它是左结合的,所以a >>= b >>= c >>= d ≡ ((a >>= b) >>= c) >>= d.

如果它真的没有多大意义infixr,不是吗?>>=总是返回一个 monad,它的 RHS 接受一个函数。因此,在任何与相关联的一元表达式链中>>=都将存在于(->) r单子中,这几乎不是最有用的。

于 2012-07-03T14:58:55.243 回答