我正在阅读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值答案 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"
:
$