继我之前的问题之后,我慢慢得到了FParsec(虽然我觉得特别难以理解).
我的下一个新手F#问题是,如何从解析器创建的列表中提取数据?
例如,我将上一个问题中的示例代码加载到一个名为Parser.fs的模块中,并在一个单独的模块中添加了一个非常简单的单元测试(带有适当的引用).我正在使用XUnit:
open Xunit
[<Fact>]
let Parse_1_ShouldReturnListContaining1 () =
let interim = Parser.parse("1")
Assert.False(List.isEmpty(interim))
let head = interim.Head // I realise that I have only one item in the list this time
Assert.Equal("1", ???)
Run Code Online (Sandbox Code Playgroud)
交互式地,当我执行解析"1"时,响应是:
val it : Element list = [Number "1"]
Run Code Online (Sandbox Code Playgroud)
通过调整有效运算符列表,我可以运行解析"1 + 1"来获取:
val it : Element list = [Number "1"; Operator "+"; Number "1"]
Run Code Online (Sandbox Code Playgroud)
我需要替代我的??? 在上面的片段?我如何检查它是一个数字,而不是一个运算符等?
F#类型(包括列表)实现结构相等.这意味着如果比较包含某些F#类型的两个列表,=当类型具有相同的长度并包含具有相同属性的元素时,它将返回true.
假设Element类型是在F#中定义的区分联合(并且不是对象类型),您应该只能写:
Assert.Equal(interim, [Number "1"; Operator "+"; Number "1"])
Run Code Online (Sandbox Code Playgroud)
如果你想自己实现相等,那么你可以使用模式匹配;
let expected = [Number "1"]
match interim, expected with
| Number a, Number b when a = b -> true
| _ -> false
Run Code Online (Sandbox Code Playgroud)