Parsec和Applicative风格

时间:2012-10-25 09:01:56

标签: haskell functional-programming applicative

有人可以帮我理解如何使用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的新手

2 个答案:

答案 0 :(得分:5)

您的应用用法是正确的,您的签名不正确。尝试:

cmdParse2 :: Parsec String () String

答案 1 :(得分:4)

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