绑定解析器返回错误的类型

时间:2014-11-15 12:08:30

标签: haskell

我正在阅读haskell书,并好奇为什么绑定操作符的返回类型对我来说很奇怪

对于给定的定义

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')&lt; - p inp”应该产生 - &gt; “('r',”ohit“)”。接下来fx inp'是左关联的,所以fx应该产生字符'r'并传递给应该返回结果元组('r',“ohit”)的lambda,但是为什么z类型是([Char],char )::(x,y)

(2)如何在ghci

上打印上述情况中的z值

2 个答案:

答案 0 :(得分: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"

答案 1 :(得分:2)

假设result的类型为a -> [a](对于列表monad是什么意思return?),您遇到的问题来自于使用中缀{{1 }}

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"

解决此问题
$