문제

Following up my previous question, I'm slowly getting the hang of FParsec (though I do find it particularly hard to grok).

My next newbie F# question is, how do I extract data from the list the parser creates?

For example, I loaded the sample code from the previous question into a module called Parser.fs, and added a very simple unit test in a separate module (with the appropriate references). I'm using 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", ???) 

Interactively, when I execute parse "1" the response is:

val it : Element list = [Number "1"]

and by tweaking the list of valid operators, I can run parse "1+1" to get:

val it : Element list = [Number "1"; Operator "+"; Number "1"]

What do I need to put in place of my ??? in the snippet above? And how do I check that it is a Number, rather than an Operator, etc.?

도움이 되었습니까?

해결책

F# types (including lists) implement structural equality. This means that if you compare two lists that contain some F# types using =, it will return true when the types have the same length and contain elements with the same properties.

Assuming that the Element type is a discriminated union defined in F# (and is not an object type), you should be able to write just:

Assert.Equal(interim, [Number "1"; Operator "+"; Number "1"])

If you wanted to implement the equality yourself, then you could use pattern matching;

let expected = [Number "1"]
match interim, expected with
| Number a, Number b when a = b -> true
| _ -> false
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top