Поскольку это больше похоже на обучение вопрос, я постараюсь дать несколько намеков, а не полный ответ.
В то время как GetType
может (в данном случае) использоваться для проверки того, имеют ли два значения раздельного объединения один и тот же случай, это не особенно функциональный стиль. Вам нужно будет использовать сопоставление с образцом, чтобы проверить, что случай у вас есть, что также позволяет извлекать численное значение:
match a with
| Litre(n) -> // Do something with 'n'
// Add all the other cases here
Я думаю, что первая вещь, чтобы рассмотреть то, что вы хотите получить в результате - Полагаю, самым простым вариантом было бы получить четыре числа, представляющие общее количество литров, галонов, ведер и бушелей.
let rec sumSameTypes (list:volume list) : float * float * float * float =
match list with
| [] ->
// For empty list, we just have 0 of everything
0.0, 0.0, 0.0, 0.0
| x::xs ->
// For non-empty list, process the rest recrsively
// and pattern match on `x` to figure out which of
// the numbers you need to increment
Это довольно простой подход, но я думаю, что это лучший способ начать работу. В общем, вы можете использовать что-то вроде карты (от единиц до значений), но тогда это также имеет смысл использовать тип, который больше похож:
type Unit = Litre | Galon | Bushel | Bucket
type Volume = { Amount : float; Unit : Unit }
Это сделало бы его гораздо проще, так как вы могли бы использовать Map<Unit, float>
как результат.
Но все-таки я дон Не понимаю, как добавить значение n; '| x :: xs -> match x with' '| Литер (n) -> // и теперь что? ' –
Вам нужно вызывать' sumSameTypes' рекурсивно на 'xs', чтобы получить итоговые литы, галоны и т. Д. Для остальной части списка, а затем добавить' n' в один возвращаемых номеров - в зависимости от типа тома, на который вы смотрите. –
Не могли бы вы написать его как код? Я начинаю работать в функциональном программировании, и я не совсем понимаю, как получить одну из возвращаемых чисел этого типа '(float * float * float * float)' для этой функции. –