【问题标题】:Parsec and Applicative styleParsec 和 Applicative 风格
【发布时间】:2012-10-25 09:01:55
【问题描述】:

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

【问题讨论】:

  • 你的错误好像你写的是(++) &lt;$&gt; ...而不是(:) &lt;$&gt; ...
  • 抱歉,已修复 .. 我正在尝试使用 ++ 和 : 并搞混了
  • 经过深入研究的终极问题,因为答案是“做得好,选择正确,做得正确,但要修复这个小类型错误。” +1

标签: haskell functional-programming applicative


【解决方案1】:

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

cmdParse2 :: Parsec String () String

【讨论】:

  • 只是一个简单的问题,是否可以从“许多 alphaNum”中获取类型文本?所以如果我想使用文本而不是字符串,我并不总是手动打包它?
  • @Arg 1. 是的。您可以转换:(pack &lt;$&gt; many alphaNum),但您需要转换所有内容:cmdParse3 = cons &lt;$&gt; char '/' &lt;*&gt; (pack &lt;$&gt; many alphaNum),但最好写成cmdParse4 = pack &lt;$&gt; cmdParse2,它可能会更好,这取决于您的应用程序将其保留到最后并执行pack &lt;$&gt; myTopLevelParser。 (您可能对Text.Parsec.Text 也有兴趣更改源数据。) 2. 为什么?您一次构建一个字符的字符串,将它们组合在一起是一种好方法。无论如何,append 对于文本来说是 O(n)
  • 好的,谢谢你的提示。顺便说一句,太棒了,haskell 在文档中的操作具有功能复杂性
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2015-03-06
    • 2015-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 2011-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多