2017-04-13 46 views
1

这是来自在线课程的任务。我已经坐了两天了。请给出一些解释或提示来解决它。自制“Many1”解析器

这里的类型

newtype Prs a = Prs { runPrs :: String -> Maybe (a, String) } 

我需要实现many1解析器。这是它应该如何工作

> runPrs (many1 $ char 'A') "AAABCDE" 
Just ("AAA","BCDE") 
> runPrs (many1 $ char 'A') "BCDE" 
Nothing 

我有解析器many实现这样的

many p = (:) <$> p <*> many p <|> pure [] 

下面是前面的例子输出。

*Main> test9 
Just ("AAA","BCDE") 
*Main> test10 
Just ("","BCDE") 

注意最后的结果,它返回空字符串,但many1应该返回Nothing。我不知道如何改变many的代码来使得像many1这样的工作。我不能想象如何停止第一个不正确的符号。

回答

3

你的many1需要一些失败的方法:正如你写的那样,它会消耗一段时间的字符,把它们带到一个未决的结果上,直到它最终用完匹配。这不包括解析可能失败的任何情况。

你在这里实现的方式是many0,它是一个消耗0次或更多次重复的解析器。你能想出一种方法来实现根据many0?它看起来是这样的:

  1. 消耗p一个实例,没有万一失败
  2. 消耗p 0以上的情况下,返回[]当失败的替代品。

或者在Haskell,

many1 :: Prs a -> Prs [a] 
many1 p = (:) <$> p <*> many0 p 
+0

谢谢你,它适用于例如案件,现在我的想法。但不幸的是,它在其他一些测试中的分级系统上失败了。 – StalkAlex

+0

它的工作原理,再次感谢伟大的解释! – StalkAlex