解析器函数中的故障处理

Failure handling in a Parser function

我正在学习使用 Trifecta library. I was introduced to Alternative 类型类及其 <|> 函数的解析器组合器。

我的代码中有一个解析器函数,其定义是

fractionOrDecimal :: Parser DoubleOrRational
fractionOrDecimal =
        (Left <$> try parseDecimal)                  -- A
    <|> (Right <$> try parseFraction)                -- B
    <|> (fail  "Expected Fraction or Decimal.")      -- Err

它尝试将输入解析为小数或分数,如果无效则失败。这种方法是否正确,或者我应该对失败 (fail) 进行不同的编码,而不是作为 <|> 操作的一部分。

失败是由缺少成功的解析器编码的。 Trifecta 将为您跟踪预期的标记,但您必须使用 <?> 告诉它它们的名称。所以你会做

fractionOrDecimal :: Parser DoubleOrRational
fractionOrDecimal =
        (Left  <$> try parseDecimal  <?> "Decimal")
    <|> (Right <$> try parseFraction <?> "Fractional")

我们现在得到这样的错误:

>>> parseTest fractionalOrDecimal "neither fractional nor decimal"
error: expected: Decimal, Fractional
neither fractional nor decimal<EOF> 
^