I have exercise to propose function that sum every value of the same type from discriminated union list like that:
type volume =
| Litre of float
| Galon of float
| Bucket of float
| Bushel of float
let list = [Litre(20.0);Litre(30.0);Galon(2.0);Bucket(5.0);Litre(5.0);Galon(3.0)];
Where output should looks like this:
[Litre(55.0);Galon(5.0);Bucket(5.0)]
I've come with part of the solution:
let rec sumSameTypes (list:volume list) =
match list with
| a::b::t -> if a.GetType() = b.GetType() then // and there is part where I don't know how to sum two of these elements
| [] -> failwith "EMPTY"
As this looks more like a learning question, I will try to give a few hints rather than a complete answer.
While GetType
can (in this case) be used to check if two discriminated union values are of the same case, this is not particularly functional style. You will need to use pattern matching to check what case you've got, which also allows you to extract the numerical value:
match a with
| Litre(n) -> // Do something with 'n'
// Add all the other cases here
I think the first thing to consider is what do you want to get as the result - I suppose the easiest option would be to get four numbers representing the total number of litres, galons, buckets and bushels.
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
This is quite basic approach, but I think it is the best way to get started. In general, you might use something like a map (from units to values), but then it would also make sense to use a type that looks more like:
type Unit = Litre | Galon | Bushel | Bucket
type Volume = { Amount : float; Unit : Unit }
This would make it much easier as you could use Map<Unit, float>
as the result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With