10

有人可以帮助我了解如何使用 Applicative 样式来编写 Parsec 解析器吗?这是我的代码:

module Main where
import Control.Applicative hiding (many)
import Text.Parsec
import Data.Functor.Identity
data Cmd = A | B deriving (Show)

main = do
  line <- getContents
  putStrLn . show $ parseCmd line

parseCmd :: String -> Either ParseError String
parseCmd input =  parse cmdParse "(parser)" input

cmdParse :: Parsec String () String
cmdParse = do
  slash <- char '/'
  whatever <- many alphaNum
  return (slash:whatever)

cmdParse2 :: String -> Parsec String () String
cmdParse2 = (:) <$> (char '/') <*> many alphaNum

但是当我尝试编译它时,我得到以下信息:

/home/tomasherman/Desktop/funinthesun.hs:21:13:
    Couldn't match expected type `Parsec String () String'
                with actual type `[a0]'
    Expected type: a0 -> [a0] -> Parsec String () String
      Actual type: a0 -> [a0] -> [a0]
    In the first argument of `(<$>)', namely `(:)'
    In the first argument of `(<*>)', namely `(:) <$> (char '/')'
Failed, modules loaded: none.

这个想法是我希望 cmdParse2 做与 cmdParse 相同的事情,但是使用应用程序......我的方法可能完全错误,我是 haskell 的新手

4

2 回答 2

5

您的应用程序使用是正确的,您只是有一个不正确的签名。尝试:

cmdParse2 :: Parsec String () String
于 2012-10-25T09:26:39.387 回答
4

你的方法在我看来是正确的,问题是cmdParse2类型错误。它应该具有与 相同的类型cmdParse。顺便说一句,您可以char '/'在应用样式解析器中省略括号。

于 2012-10-25T09:24:27.403 回答