4 votes

Erreur FS0752 dans la déclaration F# d'une map sur une liste de fonctions

Je voudrais exécuter une liste de fonctions sur une liste de valeurs correspondantes :

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;;  

Résultat :

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

stdin(213,49) : error FS0752 : The l'opérateur 'expr.[idx]' a été utilisé un objet de type indéterminé basé sur des informations antérieures à ce point du programme point. Envisagez d'ajouter d'autres contraintes

Je voudrais exécuter : pmap2 conslist [5;8]; ; (en parallèle)

9voto

Tomas Petricek Points 118959

Si vous voulez utiliser l'accès aléatoire, vous devez utiliser des tableaux. L'accès aléatoire aux éléments d'une liste fonctionne, mais il est inefficace (il faut itérer sur la liste depuis le début). Une version utilisant des tableaux ressemblerait à ceci :

// 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

Cependant, vous pouvez également réécrire l'exemple pour travailler avec n'importe quelle séquence (y compris les tableaux et les listes) en utilisant l'attribut Seq.zip fonction. Je pense que cette solution est plus élégante et qu'elle ne vous oblige pas à utiliser des tableaux impératifs (et elle n'a pas l'inconvénient des performances) :

// 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

3voto

sepp2k Points 157757

Comme le message d'erreur le suggère, vous devez ajouter des annotations de type à list1 y list2 . Une fois que vous avez fait cela, cela fonctionne bien (bien que je recommande d'utiliser des tableaux au lieu de listes puisque vous y accédez de manière aléatoire).

1voto

Brian Points 82719
let pmap2 (list1:_ list) (list2:_ list)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X