2014-11-15 42 views
0

我讀哈斯克爾書和好奇,爲什麼綁定運營商的返回類型看起來很奇怪我綁定語法分析器返回錯誤類型

對於給定的定義

type Parser a = String -> [(a, String)] 

item :: Parser Char 
item = \inp -> case inp of 
        [] -> [] 
        (x:xs) -> [(x,xs)] 

bind :: Parser a -> (a -> Parser b) -> Parser b 
p `bind` f = \inp -> concat [ f x inp' | (x, inp') <- p inp] 

,當我在GHCI定義將z作爲

let z = item `bind` (\x -> (\y -> result (x,y))) "Rohit" 

返回類型爲

>> :t z 
z :: Parser ([Char], Char) 

問題: (1)不應該返回類型(Char,[Char])? 「(x,inp')< -p inp」should yield - >「('r',」ohit「)」。下一個fx inp'是左聯合的,因此fx應該產生字符'r'並傳遞給應該返回結果元組('r',「ohit」)的lambda表達式,但爲什麼z類型是([Char],char )::(X,Y)

(2)如何打印z的值在上述情況下的ghci的

回答

2

假設result是類型a -> [a](你的意思是return的單子列表?),你遇到的問題來自於你使用中綴bind

item `bind` (\x -> (\y -> result (x,y))) "Rohit" 

被解析爲

bind item ((\ x y -> result (x, y)) "Rohit") 

,而不是你所期望的,我認爲是:

bind item (\ x y -> result (x, y)) "Rohit" 

您可以通過使用$解決這個問題:

let z = item `bind` (\x -> (\y -> result (x,y))) $ "Rohit" 
+0

非常感謝,我會記住這個☺ –

+0

我嘗試了建議,但得到了下面的異常* Main> let z = item'bind' (\ x - >(\ y - > result(x,y)))$「Rohit」 :89:35: 無法與'[(b0,String)]'' 期望的類型:[(b0,String)]匹配類型'String - > [((Char,String),String)]' 實際類型:Parser(Char,String) 在'result'調用的返回類型中 可能的原因:'result'應用於太少參數 在表達式中:result(x,y) 在表達式:(\ y - > result(x,y)) –

+0

'result'的類型是什麼?它沒有在你的代碼片段中定義。 – gallais

2

我不確定什麼result在這裏,但是這是關聯的問題。考慮你的z

let z = item `bind` (\x -> (\y -> result (x,y))) "Rohit" 

這相當於

let z = item `bind` ((\x -> (\y -> result (x,y))) "Rohit") 
     = item `bind` (\y -> result ("Rohit",y)) 

我相信你會得到你加入下面的括號渴望的結果:

let z = (item `bind` (\x -> (\y -> result (x,y)))) "Rohit" 
+0

主要>讓z =(item'bind'(\ x - >(\ y - > result(x,y) ))) 「羅希特夏爾」 :91:36: 無法匹配類型'字符串 - > [((字符,字符串),字符串)] ' 用'[(B0,字符串)]' 預期類型:[(b0,String)] 實際類型:解析器(Char,字符串) 在'result'調用的返回類型中 可能的原因:'result'應用於太少參數 在表達式中:result x,y) 在表達式中:(\ y - > result(x,y)) –