【问题标题】:Haskell parsec token typing conditionHaskell 解析令牌输入条件
【发布时间】:2020-09-21 16:06:00
【问题描述】:

考虑最小化的代码:

module Parser where

import Text.ParserCombinators.Parsec
import Text.Parsec.Pos

oneTokenP f = token show (\_ -> initialPos "Dummy") f
oneToken t = token show (\_ -> initialPos (show t)) 
                  (\t' -> if t == t' then Just () else Nothing)

我得到错误:

Parser.hs:8:1: error:
    • Non type-variable argument
        in the constraint: Text.Parsec.Prim.Stream
                             s Data.Functor.Identity.Identity a1
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        oneTokenP :: forall u s a a1.
                     (Show a1,
                      Text.Parsec.Prim.Stream s Data.Functor.Identity.Identity a1) =>
                     (a1 -> Maybe a) -> Text.Parsec.Prim.Parsec s u a

Parser.hs:9:1: error:
    • Non type-variable argument
        in the constraint: Text.Parsec.Prim.Stream
                             s Data.Functor.Identity.Identity a
      (Use FlexibleContexts to permit this)
    • When checking the inferred type
        oneToken :: forall u s a.
                    (Eq a, Show a,
                     Text.Parsec.Prim.Stream s Data.Functor.Identity.Identity a) =>
                    a -> Text.Parsec.Prim.Parsec s u ()

我违反了哪个打字条件?

根据@amalloy 的建议重写:

oneTokenP f = token showTok posFromTok testTok
 where
     showTok (pos,t) = show t
     posFromTok (pos,t) = initialPos "Dummy"
     testTok (pos,t) = f t
oneToken x = token showTok posFromTok testTok
 where 
     showTok (pos,t) = show t
     posFromTok (pos,t) = initialPos (show t)
     testTok (pos,t) = if x == t then Just () else Nothing

【问题讨论】:

  • 解析器在其推断类型中有一个Stream s Identity a 约束。因为Identity 是具体类型,而不是类型变量,所以这不是Haskell98,它要求约束的形式为Class var1 … varn。为此,您可以使用{-# LANGUAGE FlexibleContexts #-} pragma 或-XFlexibleContexts 标志打开FlexibleContexts 扩展; this 和 FlexibleInstances(允许在 instance 定义中使用相同的东西)是非常良性的扩展并且非常常用。

标签: haskell parsec


【解决方案1】:

将你的函数与the example in the documentation for token进行比较:

 mytoken x
   = token showTok posFromTok testTok
   where
     showTok (pos,t)     = show t
     posFromTok (pos,t)  = pos
     testTok (pos,t)     = if x == t then Just t else Nothing

在每一个中,输入都是位置和标记的元组。您正试图将这样的元组视为只是一个标记。我不清楚为什么这个错误会产生你得到的特定错误,但我认为你仍然可以看到这是一个错误。

【讨论】:

    【解决方案2】:

    错误信息提示

    (Use FlexibleContexts to permit this)
    

    所以,我们可以添加

    {-# LANGUAGE FlexibleContexts #-}
    

    在文件的顶部。之后就可以正常编译了。

    【讨论】:

      猜你喜欢
      • 2013-05-26
      • 2013-06-27
      • 2013-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      • 2013-05-28
      • 2016-01-11
      相关资源
      最近更新 更多