Reputation: 451
Is it possible to iterate through an array using pattering matching just like we do with lists in F#? I tried something like this:
type Alphabet = A | B
let rec calc (l: Alphabet []) = match l with
|l when l.[0] = A -> 5+(calc l.[1..])
|l when l.[0] = B -> 10+(calc l.[1..])
|l when l = [||] -> 0
calc [|A;A;B|]
The problem seems to be that the loop goes on and results a stackoverflow. Is it possible to do so?
Upvotes: 3
Views: 1516
Reputation: 6223
I think you are trying to do this:
let toInteger = function
| A -> 5
| B -> 10
[|A; A; B|] |> Array.sumBy toInteger
In pattern matching, you can use an array pattern: for example, [|a; b; c|]
matches against a three-element array. But there is no ::
operator for arrays, so it's cumbersome to use an array the way you'd use a list. This is because you can't get the array's tail as a new array without copying it.
There are a number of issues with the question's code:
.[1..]
slice exists.Array.sumBy
or a tail-recursive function indexing into the array, which don't have to copy the array at all.The heart of the issue here is the difference between arrays and singly linked immutable lists. Arrays are suited for iterating over them by increasing an index (which Array.sumBy
does internally), while lists allow to treat their tail as an independent list without any copying (which List.sumBy does internally
). It's usually best to use each data structure the way it is intended to be used.
Upvotes: 8