Вопрос
Следуя Мой предыдущий вопрос, Я постепенно получаю витрину 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", ???)
Интерактивно, когда я выполняю parse "1" Ответ:
val it : Element list = [Number "1"]
и настроив список действительных операторов, я могу запустить Parse "1+1" получить:
val it : Element list = [Number "1"; Operator "+"; Number "1"]
Что мне нужно поместить вместо моего ??? в фрагменте выше? И как я могу проверить, что это число, а не оператор и т. Д.?
Решение
Типы 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