【问题标题】:bind parser returning wrong type绑定解析器返回错误的类型
【发布时间】:2014-11-15 12:08:29
【问题描述】:

我正在阅读 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')“('r',“ohit”)”。下一个 f x inp' 是左关联的,所以 f x 应该产生字符 'r' 并传递给应该返回结果元组 ('r', "ohit") 的 lambda,但是为什么 z 类型是 ([Char], char ) :: (x,y)

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

【问题讨论】:

    标签: haskell


    【解决方案1】:

    假设resulta -&gt; [a] 类型(您的意思是return 用于列表monad?),您遇到的问题来自您使用中缀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"
    

    【讨论】:

    • 非常感谢,我会记住的☺
    • 我按照建议尝试了,但得到了以下异常 *Main> let z = item bind (\x -> (\y -> result (x,y))) $ "Rohit" :89:35: 无法匹配类型 String -&gt; [((Char, String), String)]' with [(b0, String)]' 预期类型:[(b0, String)] 实际类型:Parser (Char, String) 在调用的返回类型中result' Probable cause: result' 应用于太少的参数 表达式中:result (x, y) 表达式中:(\y -> result (x, y))
    • result的类型是什么?它没有在你的 sn-p 中定义。
    【解决方案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"
    

    【讨论】:

    • Main> let z = (item bind (\x -> (\y -> result (x,y)))) "Rohit" :91:36: couldn' t match type String -&gt; [((Char, String), String)]' with [(b0, String)]' 预期类型:[(b0, String)] 实际类型:Parser (Char, String) 在result' Probable cause: result'的调用的返回类型中也适用几个参数 在表达式中:result (x, y) 在表达式中:(\ y -> result (x, y))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    相关资源
    最近更新 更多