Как извлечь данные из списка F # - PullRequest
3 голосов
/ 16 января 2011

В ответ на мой предыдущий вопрос , я постепенно осваиваю 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", ???) 

Интерактивно, когда я выполняю синтаксический анализ "1" ответ:

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

и путем настройки списка действительныхоператоры, я могу запустить синтаксический анализ "1 + 1" , чтобы получить:

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

Что мне нужно поставить вместо моих ??? вфрагмент выше?И как мне проверить, что это номер, а не оператор и т. Д.? 1022 *

1 Ответ

7 голосов
/ 16 января 2011

F # типы (включая списки) реализуют структурное равенство. Это означает, что если вы сравните два списка, которые содержат некоторые типы F #, используя =, он вернет true, если типы имеют одинаковую длину и содержат элементы с одинаковыми свойствами.

Предполагая, что тип Element является дискриминируемым объединением, определенным в F # (и не является типом объекта), вы можете написать просто:

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

Если вы хотите реализовать равенство самостоятельно, то можете использовать сопоставление с образцом;

let expected = [Number "1"]
match interim, expected with
| Number a, Number b when a = b -> true
| _ -> false
...