F #: использование List.map для вызова методов в последовательности методов

#generics #f#

#обобщения #f#

Вопрос:

В принципе, у меня есть список методов, которые я хочу повторить, вызвать методы и вернуть список возвращаемых значений метода. Я могу заставить это работать с синтаксисом Linq.

 member public x.TakeIn(methodList : seq<(String -> Int32)>, input:String) =
    methodList.Select((fun (item:String -> Int32) -> item(input))).ToList()
  

Однако я не могу заставить map тоже работать, что, как я предполагаю, связано с моим отсутствием знаний синтаксиса F #.

 member public x.TakeIn(methodList : seq<(String -> Int32)>, input:String) =
    methodList |> List.map (fun (item) -> item(input))
  

Не должно ли это означать, что метод map будет принимать в последовательности<(String -> Int32)> , выполнять итерации, вызывать каждый метод и возвращать список Int32?

Комментарии:

1. Обратите внимание, что если вы удалите ToList в своей версии C #, вы получите ту же проблему.

Ответ №1:

Поскольку methodList это последовательность в F #, вы не можете рассматривать ее как список (который является одним из его подтипов). Поэтому убедитесь, что вы используете функции высокого порядка для последовательности и преобразуете результат в список:

 member public x.TakeIn(methodList : seq<(String -> Int32)>, input:String) =
    methodList |> Seq.map (fun (item) -> item(input)) |> Seq.toList
  

Ответ №2:

Для List.map требуется list<‘a>, но вы явно заявляете, что methodList является seq<..> . Возможные решения:

 // 1. type of methods will be inferred as list
let takeIn (methods, input : string) : int list = 
    methods 
    |> List.map (fun f -> f input) 
// 2. explicitly convert result to list 
let takeIn (methods, input : string) : int list = 
    methods 
    |> Seq.map (fun f -> f input) 
    |> Seq.toList 
// 3. same as 2 but using list sequence expressions
let takeIn (methods, input : string) : int list = [for f in methods do yield f input]