2012-07-03 29 views
6

Trong this hướng dẫn, tôi đã tìm thấy các đoạn mã sau:lẽ đơn nguyên function bind ưu tiên

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 

tôi không thể tìm ra cách các chức năng >>= là nghĩa vụ phải làm việc. Lúc đầu, giá trị Maybe a là tham số đầu tiên: deposit 100 account >>=

Sau đó, có vẻ như tham số đầu tiên: withdraw 200 >>= Làm cách nào để trình biên dịch này có thể chấp thuận? Không nên >>= luôn lấy Maybe a làm thông số đầu tiên?

Một giải pháp có thể sẽ là nếu ưu tiên các >>= chức năng của sẽ làm việc theo cách sau: ((a >>= b) >>= c) >>= d

Nhưng như xa như tôi biết, nó là ngược lại: a >>= (b >>= (c >>= d))

+2

Bạn có thể đã nhầm lẫn nó với ký hiệu 'do':' do a <- b; c <- d; e' là 'b >> = (\ a -> d >> = (\ c -> e))'. – sdcvvc

+0

@sdcvvc: Cảm ơn bạn, đây thực sự là nguồn gốc của sự nhầm lẫn của tôi. – kahoon

+0

Cũng lưu ý rằng nó không phải là "Có thể ưu tiên chức năng liên kết monad"; bạn không thể có các ưu tiên khác nhau cho các trường hợp typeclass khác nhau, do đó, nó sẽ phải là ưu tiên cho các liên kết * all * monads '. – Ashe

Trả lời

14

như xa như tôi biết , đối diện: a >>= (b >>= (c >>= d))

không.

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

infixl có nghĩa là liên kết bên trái, vì vậy a >>= b >>= c >>= d ≡ ((a >>= b) >>= c) >>= d.

Nó sẽ không thực sự có ý nghĩa nhiều nếu nó là infixr, phải không? >>= luôn trả về một đơn nguyên, và RHS của nó có chức năng. Vì vậy, trong bất kỳ biểu thức monoic nào được liên kết với >>= sẽ nằm trong đơn vị (->) r, vốn không phải là biểu tượng hữu ích nhất.