Permutation un sémaphores
En fait, nous pouvons le faire deux modèles possibles suivants:
- [1,2,3,4, ..] devient [1,3,5,7 ...]
- [1,2,3,4, ..] devient [2,4,6,8 ...]
les deux font la même chose, mais ils "commencent le comptage" le chemin inverse. Laissez-nous mettre en œuvre les deux avec la même fonction! Bien sûr, cette fonction doit être paramétrée selon le "pattern". Deux modèles possibles existent, donc, nous avons besoin d'un booléen pour le type pour la paramétrisation. Mise en œuvre: laissez-nous utiliser un paramètre booléen comme un « drapeau », « sémaphores »:
module Alternation where
every_second :: [a] -> [a]
every_second = every_second_at False
every_second_at :: Bool -> [a] -> [a]
every_second_at _ [] = []
every_second_at True (x : xs) = x : every_second_at False xs
every_second_at False (x : xs) = every_second_at True xs
Nous avons utilisé une fonction auxiliaire, la comptabilité du « drapeau/sémaphores »: il est swapping en conséquence. En fait, cette fonction auxiliaire peut être considérée comme une généralisation de la tâche d'origine. Je pense, c'est ce qu'on appelle une fonction "worker wrapper".
Compte à rebours avec un indice
La tâche peut être généralisée encore plus loin. Pourquoi ne pas écrire une fonction beaucoup plus générale, qui peut être paramétrée par un "modulus" m, et il "récolte" tout me elems d'une liste?
- every_mth 1 [1,2,3,4, ...] [rendements 1,2,3,4 ...]
- every_mth 2 [1,2,3,4, .. .] [rendements 1,3,5 ...]
- every_mth 3 [1,2,3,4, ...] [rendements 1,4,7 ...]
Nous pouvons utiliser les mêmes idées qu'auparavant, il suffit d'utiliser un "sémaphore" plus compliqué: un nombre naturel au lieu d'un booléen. Ceci est un paramètre "compte à rebours", un indice i la comptabilité quand il est à notre tour:
module Cycle where
import Nat (Nat)
every_mth :: Nat -> [a] -> [a]
every_mth 0 = undefined
every_mth m @ (i + 1) = every_mth_at m i
Nous utilisons une fonction auxiliaire (worker wrapper), la comptabilité de l'indice du compte à rebours i:
every_mth_at :: Nat -> Nat -> [a] -> [a]
every_mth_at _ _ [] = []
every_mth_at m 0 (x : xs) = x : every_mth m xs
every_nth_at m (i + 1) (x : xs) = every_mth_at m i xs
Par souci de simplicité, le type de nombre naturel est « mis en œuvre » ici comme un simple alias:
module Nat (Nat) where
type Nat = Integer
Peut-être, dans un certain nombre de sens théorétique, il y a aussi d'autres approches plus propres, pas exactement équivalent à la tâche que vous avez spécifié, mais réglage semble être simple:
- let
every_mth 1 [0,1,2,3,4,...]
rendement [0,1,2,3,4,...]
- let
every_mth 2 [0,1,2,3,4,...]
rendement [0,2,4,6,8...]
- nous
every_mth 3 [0,1,2,3,4,...]
donné [0,3,6,9...]
ainsi, il est précisé ici pour qu'il devrait fournir « incidemment » les lis t de multiples du paramètre, lorsqu'il est appliqué à la liste paresseuse de tous les nombres naturels.
Dans sa mise en œuvre, il vaut la peine d'utiliser des nombres comme un index «basé sur zéro». Au lieu de "tous les me", nous disons: « utiliser i comme un indice allant de 0, 1, ..., u =m -1, où u représente la limite supérieure des indices possibles. Cet indice supérieur peut être un paramètre utile dans la fonction auxiliaire, qui compte à rebours l'indice.
module Multiple where
import Nat (Nat)
every_mth :: Nat -> [a] -> [a]
every_mth 0 = undefined
every_mth (u + 1) = countdown u
countdown :: Nat -> [a] -> [a]
countdown = countdown_at 0
countdown_at :: Nat -> Nat -> [a] -> [a]
countdown_at _ _ [] = []
countdown_at 0 u (x : xs) = x : countdown_at u u xs
countdown_at (i + 1) u (x : xs) = countdown_at i u xs
d'autres ont répondu à ce problème, donc je vais faire un point plus général. Vous pensez impérieusement : d'abord trouver la longueur de la liste puis, si c'est impair, obtenir le premier élément, puis appeler la fonction pour obtenir le reste de la liste. liste, puis placez l'élément devant. Ce que vous devez faire est de penser en termes d'expressions et d'équations.Le résultat que vous voulez est le premier élément de la liste suivi du résultat de l'application du fait à la queue de la queue. Puis traduisez cela en Haskell. –