首页 > 解决方案 > Haskell 解析令牌输入条件

问题描述

考虑最小化的代码:

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

标签: haskellparsec

解决方案


将您的函数与文档中的示例进行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

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


推荐阅读