F# forces my unspecifed type to be a bool.
I needed a combination of List.find and List.tryPick, and made the function below. Efficiancy is not important.
What did i do wrong for type 'T to only be able to be type bool?
let FindPickCombi(list : 'T list, func : 'T -> 'U option) : bool * ('U option) =
(List.find
(fun (x : 'T) ->
match func(x) with
| Some _ -> true
| _ -> false
) list,
List.tryPick(fun x -> func(x)) list)
CodePudding user response:
I found the answer myself. The return type shouldn't have been bool.
Changed function to:
let FindPickCombi(list : 'T list, func : 'T -> 'U option) : 'T * ('U option) =
(List.find
(fun (x) ->
match func(x) with
| Some _ -> true
| _ -> false
) list,
List.tryPick(fun x -> func(x)) list)
CodePudding user response:
Your current solution in your own answer loops twice over the whole list. Also, the first part with List.find
will fail with a KeyNotFoundException
if nothing is found, meaning that the tryPick
will never return None
.
Here's an alternative, which returns both the original type of the list
and the mapped typed from your func
. We wrap the whole tuple in an option
.
let FindPickCombi(list : 'T list, func : 'T -> 'U option) : ('T * 'U) option =
List.tryPick(fun x ->
match func x with
| Some y -> Some(x, y)
| None -> None) list
This can be further improved by ditching the (list, func)
tuple, so that our function can use currying / partial application, which further simplifies the code and uses the same order of arguments as F#'s build-in functions (that is: the function-argument comes first).
As you can see here, we don't have the list
argument anymore, because that is curried from List.tryPick
automatically by F#:
let FindPickCombi func =
List.tryPick(fun x ->
match func x with
| Some y -> Some(x, y)
| None -> None)
What did i do wrong for type 'T to only be able to be type bool?
You made the return type of your function bool * 'U option
, which is why the compiler forces the result of List.find
to be a bool, which makes the type of 'T list
a list of bools.