Ошибка FS0752 в F # объявлении карты над списком функций - PullRequest
4 голосов
/ 30 января 2011

Я хотел бы выполнить список функций над списком соответствующих значений:

let f1 x = x*2;;  
let f2 x = x+70;;

let conslist = [f1;f2];;

let pmap2 list1 list2 =   
  seq { for i in 0..1 do yield async { return list1.[i] list2.[i] } }  
  |> Async.Parallel  
  |> Async.RunSynchronously;;  

Результат:

  seq { for i in 0..1 do yield async { return list1.[i] list2.[i] } }
----------------------------------------------^^^^^^^^^

stdin (213,49): ошибкаFS0752: оператор 'expr. [Idx]' использовал объект неопределенного типа, основанный на информации до этой программной точки.Попробуйте добавить дополнительные ограничения типа

Я хотел бы выполнить: pmap2 conslist [5; 8] ;;(параллельно)

Ответы [ 3 ]

9 голосов
/ 30 января 2011

Если вы хотите использовать произвольный доступ, вам следует использовать массивы.Произвольный доступ к элементам списка будет работать, но он неэффективен (он должен перебирать список с самого начала).Версия, использующая массивы, будет выглядеть следующим образом:

// Needs to be declared as array
let conslist = [|f1; f2|];; 

// Add type annotations to specify that arguments are arrays
let pmap2 (arr1:_[]) (arr2:_[]) = 
  seq { for i in 0 .. 1 do 
          yield async { return arr1.[i] arr2.[i] } }
  |> Async.Parallel |> Async.RunSynchronously

Однако вы также можете переписать пример для работы с любыми последовательностями (включая массивы и списки), используя функцию Seq.zip.Я думаю, что это решение более элегантно и не заставляет вас использовать императивные массивы (и оно не имеет недостатка в производительности):

// Works with any sequence type (array, list, etc.)
let pmap2 functions arguments = 
  seq { for f, arg in Seq.zip functions arguments do 
          yield async { return f arg } }
  |> Async.Parallel |> Async.RunSynchronously
3 голосов
/ 30 января 2011

Как следует из сообщения об ошибке, вам необходимо добавить аннотации типов к list1 и list2. Как только вы это сделаете, все будет работать нормально (хотя я бы порекомендовал использовать массивы вместо списка, так как вы получаете к ним произвольный доступ).

1 голос
/ 30 января 2011
let pmap2 (list1:_ list) (list2:_ list)
...