拆包嵌套的应用函子 f#
Unpacking nested applicative functors f#
你好我正在尝试制作一个组合器解析器,我目前正在尝试让它读取 headers 并根据解析的 header 创建解析器。即 header 的; int、float、string 将导致 Parser<Parser<int>*Parser<float>*Parser<string>>
。
不过我想知道您将如何解压缩 "inner" 解析器,然后得到类似的东西; Parser<int*float*string>?
解析器类型是:type Parser<'a> = Parser of (string -> Result<'a * string, string>)
我不确定您使用嵌套解析器的想法是否可行 - 如果您动态解析 header,那么您将需要生成相同类型的解析器列表。你写这个的方式暗示解析器的类型将取决于输入,这在 F# 中是不可能的。
因此,我希望您需要像这样定义一个值:
type Value = Int of int | String of string | Float of float
然后你解析 header 的解析器会产生类似这样的东西:
let parseHeaders args : Parser<Parser<Value> list> = (...)
下一个问题是,你想用嵌套解析器做什么?据推测,您需要将它们变成一个解析器来解析整行数据(如果这类似于 CSV 文件)。通常,您会定义一个函数 sequence
:
val sequence : sep:Parser<unit> -> parsers:Parser<'a> list -> Parser<'a list>
这需要一个分隔符(例如,识别逗号的解析器)和一个解析器列表,并生成一个解析器,该解析器运行将所有解析器按序列排列,中间有分隔符。
那么你可以这样做:
parseHeaders input |> map (fun parsers -> sequence (char ',') parsers)
你得到一个解析器 Parser<Parser<string>>
。您现在想要 运行 嵌套解析器位于 运行 识别 headers 的外部解析器之后剩下的部分。以下函数可以解决问题:
let unwrap (Parser f:Parser<Parser<'a>>) = Parser (fun s ->
match f s with
| Result.Ok(Parser nested, rest) -> nested rest
| Result.Error e -> Result.Error e )
你好我正在尝试制作一个组合器解析器,我目前正在尝试让它读取 headers 并根据解析的 header 创建解析器。即 header 的; int、float、string 将导致 Parser<Parser<int>*Parser<float>*Parser<string>>
。
不过我想知道您将如何解压缩 "inner" 解析器,然后得到类似的东西; Parser<int*float*string>?
解析器类型是:type Parser<'a> = Parser of (string -> Result<'a * string, string>)
我不确定您使用嵌套解析器的想法是否可行 - 如果您动态解析 header,那么您将需要生成相同类型的解析器列表。你写这个的方式暗示解析器的类型将取决于输入,这在 F# 中是不可能的。
因此,我希望您需要像这样定义一个值:
type Value = Int of int | String of string | Float of float
然后你解析 header 的解析器会产生类似这样的东西:
let parseHeaders args : Parser<Parser<Value> list> = (...)
下一个问题是,你想用嵌套解析器做什么?据推测,您需要将它们变成一个解析器来解析整行数据(如果这类似于 CSV 文件)。通常,您会定义一个函数 sequence
:
val sequence : sep:Parser<unit> -> parsers:Parser<'a> list -> Parser<'a list>
这需要一个分隔符(例如,识别逗号的解析器)和一个解析器列表,并生成一个解析器,该解析器运行将所有解析器按序列排列,中间有分隔符。
那么你可以这样做:
parseHeaders input |> map (fun parsers -> sequence (char ',') parsers)
你得到一个解析器 Parser<Parser<string>>
。您现在想要 运行 嵌套解析器位于 运行 识别 headers 的外部解析器之后剩下的部分。以下函数可以解决问题:
let unwrap (Parser f:Parser<Parser<'a>>) = Parser (fun s ->
match f s with
| Result.Ok(Parser nested, rest) -> nested rest
| Result.Error e -> Result.Error e )