2012-07-03 38 views
6

this教程中,我发现下面的代码片段:也许单子绑定功能优先

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))

+2

您可能会将它与'do'表示法混淆:'do a < - b; c < - d; e'是'b >> =(\ a→d >> =(\ c→e))'。 – sdcvvc

+0

@sdcvvc:谢谢,这确实是我混乱的根源。 – kahoon

+0

还要注意它不是“Maybe monad bind function precedence”;对于不同的类型实例,不能有不同的优先级,所以它必须是* all * monads绑定的优先级。 – Ashe

回答

14

据我所知,它是相反的:a >>= (b >>= (c >>= d))

nope。

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采用一个函数。因此,在中,与>>=链接的任何 monadic表达式链将位于(->) r monad中,这几乎不是最有用的一个。