2013-12-21 150 views
2

我剛剛從this wikibook開始學習Haskell,並且在練習中遇到了一些問題。部分函數在Haskell中的應用

具體來說,如我所料

parseNumber :: Parser LispVal 
parseNumber = (many1 digit) >>= (return $ Number . read) 

除非我微微

parseNumber :: Parser LispVal 
parseNumber = (many1 digit) >>= (\n -> return $ Number . read $ n) 

我希望有人能解釋爲什麼return $ Number . read不計算爲同一拉姆達變化它下面不工作函數,我明確地在第二個定義中創建,因爲我認爲這正是部分函數評估在使用無點樣式代碼時所做的(顯然不是!)

感謝您的任何幫助,希望它不是另一個初學者的monad問題...

+1

'return。號碼。閱讀'應該工作,但。 – Ingo

回答

4

這只是$如何關聯的問題。從根本上說,$只是一個用於編寫較少括號的操作符;這與將括號包裝到表達式的末尾是一樣的。

使用這個想法,我們可以重寫你的第二個例子:

parseNumber = (many1 digit) >>= (\n -> return (Number . read (n))) 

僅供參考,原始表達式用括號看起來是這樣的:

parseNumber = (many1 digit) >>= (return (Number . read)) 

所以部分應用程序的等價物實際上是:

parseNumber = (many1 digit) >>= (\n -> (return (Number . read)) n) 

基本上,將多個$關聯關係與您的預期不同。

+0

感謝您的回答,儘管我有點理解'$'是如何聯繫的 - 我只是想象它在最後留下了某種空洞/佔位符,現在看起來很愚蠢。當我在方案中想象這一點時(如果它有部分應用),我會考慮'((+)1 2)'ok,因爲應用於沒有參數的'+'本身就是你得到的'(+ 1 2)',當然圓括號真的意味着'+(1,2)'所以這可能是我錯誤的地方 – user3125280

1

它看起來像你想:

parseNumber = (many1 digit) >>= (return . Number . read) 

或alteratively

parseNumber = (many1 digit) `fmap` (Number . read) 

Number . read是一個功能String -> LispVal所以return $ Number . read類型是Parser (String -> LispVal),而你需要的功能有型String -> Parser LispVal

+0

謝謝,這解決了我的問題,但我不認爲它回答我的問題最好(它仍然一樣有幫助,因爲我不'沒有看到'Parser(a - > b)'和'a-> Parser b'之間的差異) – user3125280

3

回到定義 -

($) :: (a -> b) -> a -> b 
($) = id 

(.) :: (b -> c) -> (a -> b) -> (a -> c) 
(.) f g x = f (g x) 

現在你有

return $ Number . read = ($) return (Number . read) -- (.) has higher precedence 
         = return (Number . read) 

和你所在的單子是Parser單子,所以這是試圖綁定一個解析值返回一個解析器其他功能的功能(很多層的抽象!)

相反,你要的是

return . Number . read 

這相當於你寫的,你可以通過做

\n -> return $ Number . read $ n = \n -> return . Number . read $ n -- definition of (.) 
           = return . Number . read   -- eta reduction 

終於看到,請注意,當你看到圖案

x >>= return . f 

此c一個始終與

fmap f x -- or liftM f x 

即它表明你沒有真正使用Monad例如在全部替換,而是較弱(和更普遍)Functor實例。

+0

一個完整的答案,謝謝,但你並沒有完全達到最快。就像我在接受的答案中解釋的那樣,問題是我認爲差距離開了爭論(但是在函數式語言中,這隻會是愚蠢的,因爲返回的唯一參數可能是函數),所以接受的答案更有幫助 – user3125280