我跳上了#haskell IRC頻道,問lambdabot:
11:25 < dmwit> ?src liftM
11:25 < lambdabot> liftM f m1 = do { x1 <- m1; return (f x1) }
11:27 < dmwit> ?src ($)
11:27 < lambdabot> f $ x = f x
(如果你不想問lambdabot,你也可以要求Hoogle並單擊源。鏈接的文檔中)
所以,讓我們填寫f
和m1
:
liftM (Number . read) $ many1 digit
={definition of ($)}
liftM (Number . read) (many1 digit)
={definition of liftM}
do { x1 <- (many1 digit); return ((Number . read) x1) }
={expand to layout form, eliminate redundant parentheses}
do
x1 <- many1 digit
return ((Number . read) x1)
你可以寫的這半打的變化不同的語法審美的,但這裏是我最喜歡的,擴大的(.)
和($)
幾次定義之後:
={definitions of (.) and ($)}
do
x1 <- many1 digit
return . Number . read $ x1
類型liftM'的'是'(單子米)=>(a→b)→ma→mb。在這種情況下,'liftM'是'Parser' monad中的'fmap'。但是'(Number。read)digits'不是一個monadic值,所以你遇到了一個類型錯誤(原因之一:'(Number。read)digits'不是一個函數,而是被用作函數;原因二: '(Number。read)digits'不是一個monadic值,所以它對於某個monad'm'沒有'ma'類型)。然而,在不使用'liftM'的情況下使用'return(Number(read(digits)))'是一個monadic值,並且等同於(放在最後一行時)原始定義。 – danportin