2017-03-24 2 views
0

Donc mon code donne le résultat voulu mais je me demande s'il y a un meilleur moyen de le coder. Ceci est l'exemple donné:haskell optimise le code liste infini

pair [ 1 , 2 , 3 , 4 , 5 , 6 , ... ] 
[ [ 1 , 2 ] , [ 3 , 4 ] , [ 5 , 6 ] , ... ] 

et le code donné:

pair::[a] -> [[a]] 
pair = 

Ma solution:

pair :: [a] -> [[a]] 
pair (x:y:xs) = ((x:y:[]):[]) ++ pair xs 
+0

Ne jamais concaténer les listes si vous pouvez utiliser ':': '++' dans * O (n) * (avec * n * la taille de la première liste) alors que ':' fonctionne dans * O (1) * . –

+3

@WillemVanOnsem Mais si la taille de la première liste est * O (1) * comme dans tous les cas, vous pouvez facilement remplacer '(++)' par '(:)' alors '(++)' est aussi * O (1)*. Donc, alors que '(:)' peut être un facteur constant plus rapide que '(++)' asymptotiquement, ils sont identiques. – jpath

+0

Vous n'avez pas posé de question. –

Répondre

1

Utilisation de l'opérateur contre : sera beaucoup plus performant que les listes concaténer:

pair :: [a] -> [[a]] 
pair (x:y:xs) = [x, y] : pair xs 

Le raisonnement est que les listes dans Haskell sont des listes liées où chaque élément pointe vers le suivant jusqu'à la fin de la liste. Les pushs et les pops sont bon marché quand ils sont en tête de liste parce que vous pointez seulement la tête en tête d'une liste existante. Lorsque vous concaténez deux listes liées, vous reconstruisez essentiellement la première liste complète afin que son dernier élément pointe vers le premier élément de la deuxième liste. Le gain de performance est mineur dans votre exemple puisque vous n'avez que deux éléments dans votre liste, mais en règle générale, si vous avez des opérations en tête de liste, ça sera presque toujours plus performant utiliser contre.

+0

merci beaucoup! – Lorenzo

+1

Avez-vous testé cette assertion? Dans mes tests, GHC émet le même noyau pour les deux implémentations. –

+0

Je n'ai pas testé le GHC compilé. S'il est capable d'optimiser dans ce cas précis, c'est plutôt cool et je peux mettre à jour ma réponse, mais je pense que la règle générale est valable et nous ne devrions pas coder '++' quand ':' suffira et est, au moins théoriquement , plus performant. –