Exception failwith在计算表达式-FParsec中使用时会导致错误

Exception failwith在计算表达式-FParsec中使用时会导致错误,exception,f#,fparsec,Exception,F#,Fparsec,我使用一个函数: let identifier kind = (many1Satisfy2L isLetter (fun c -> isLetter c || isDigit c) "identifier" >>= fun s -> preturn s) >>= fun s -> identifierKind s kind kind参数属于以下类型: type KindOfIdentifier = | Data

我使用一个函数:

let identifier kind =
    (many1Satisfy2L isLetter
        (fun c -> isLetter c || isDigit c) "identifier"
     >>= fun s -> preturn s) >>= fun s -> identifierKind s kind
kind
参数属于以下类型:

type KindOfIdentifier =
    | Data
    | Type
    | Module
下面是我的函数,它分析
kind
参数:

let private identifierKind (id: string) kind =
    match kind with
    | KindOfIdentifier.Data ->
        if id.ToUpper() = id && id.Length > 1 then preturn id
        elif System.Char.IsUpper id.[0] = false then preturn id
        else failwith "Error 1"
    | KindOfIdentifier.Module ->
        if System.Char.IsUpper id.[0] then preturn id
        else failwith "Error 2"
    | KindOfIdentifier.Type ->
        preturn id
因此,我想分析一个标识符,以验证它是否符合标识符类型的标准。如果识别它不符合标准,我将返回一个带有
failwith
的错误。 但是,当我在要分析的文本中使用带有故意错误的解析器(标识)来检查一切是否正常时,我会得到一个很长的错误:

(对不起,我是法国人,所以错误消息中有一点法语。)


如何防止所有这一切,并仅使用FParsec以经典方式显示错误消息?

函数的
failwith
引发.NET异常-一种catasprophic故障,该故障应指示程序以意外方式中断。或者,换言之,以一种特殊的方式——因此得名为“例外”。这不是你想做的

这里您要做的是向FParsec指出当前的解析尝试已失败,并可能提供对实际发生情况的解释

为此,您需要创建一个产生错误的
解析器实例
——与所返回的类型相同

preturn
创建一个成功的
Parser
实例时,还有一个函数创建一个产生错误的实例。此函数被调用。只要使用它:

    | KindOfIdentifier.Data ->
        if id.ToUpper() = id && id.Length > 1 then preturn id
        elif System.Char.IsUpper id.[0] = false then preturn id
        else fail "Error 1"

failwith
函数抛出一个.NET异常-一个catasprophic故障,该故障被认为指示程序以意外方式中断。或者,换言之,以一种特殊的方式——因此得名为“例外”。这不是你想做的

这里您要做的是向FParsec指出当前的解析尝试已失败,并可能提供对实际发生情况的解释

为此,您需要创建一个产生错误的
解析器实例
——与所返回的类型相同

preturn
创建一个成功的
Parser
实例时,还有一个函数创建一个产生错误的实例。此函数被调用。只要使用它:

    | KindOfIdentifier.Data ->
        if id.ToUpper() = id && id.Length > 1 then preturn id
        elif System.Char.IsUpper id.[0] = false then preturn id
        else fail "Error 1"