More efficient version of the same thing shown below. This means it is now essentially a copy of @GeneBelitski's answer.
let run input calc =
let inputList = Seq.toList input
let rec subrun inp acc =
match inp with
| [] -> (acc, "Done")
| (x :: xs) ->
let res = calc x
match res with
| Some(y) -> subrun xs (acc + y)
| None -> (acc, "Error")
subrun inputList 0
Note that this function below is EXTREMELY slow, likely because it uses Seq.tail (I had thought that would be the same as List.tail). I leave it in for posterity.
The easiest way I can think of for doing this in F# would be to use a tail-recursive function. Something like
let run input calc =
let rec subrun inp acc =
if Seq.isEmpty inp then
(acc, "Done")
else
let res = calc (Seq.head inp)
match res with
| Some(x) -> subrun (Seq.tail inp) (acc + x)
| None -> (acc, "Error")
subrun input 0
I'm not 100% sure just how efficient that would be. In my experience, sometimes for some reason, my own tail-recursive functions seem to be considerably slower than using the built-in higher-order functions. This should at least get you to the right result.
The below, while apparently not answering the actual question, is left in just in case it is useful to someone.
The typical way to handle this would be to make your calc function return either an Option or Result type, e.g.
let calc1 x = if x = 3 then None else Some(x*2)
and then map that to your input. Afterwards, you can fairly easily do something like
|> Seq.exists Option.isNone
to make see if there are Nones in the resulting seq (you can pipe it to not if you want the opposite result).
If you just need to eliminate Nones from the list, you can use
Seq.choose id
which will eliminate all Nones while leaving the Options intact.
For summing the list, assuming that you have used choose to be left with just the Somes, then you can do
Seq.sumBy Option.get