Dans votre programme, vous écrivez:
take6 n (b:bs) = ...
Mais ici, vous utilisez donc un modèle (b:bs)
qui est le constructeur des « contre » de la liste. Le contre constructeur prend une tête b
et une queue bs
. Le type de liste a cependant deux constructeurs: le "contre" dont nous avons déjà parlé ici, et la liste vide []
. Haskell se plaint de ne pas trouver de clause pour le modèle de liste vide du deuxième argument. Donc, votre fonction doit être définie avec une forme:
take6 n [] = ...
take6 n (b:bs) = ...
Maintenant, la question est encore de savoir quoi faire ici. Peu importe ce que nous prenons dans le cas d'une liste vide, nous ne pouvons émettre des éléments plus, vous voulez probablement retourner la liste vide, donc:
take6 _ [] = []
En outre, vous permettent en effet une distinction entre n
étant inférieure ou égal à zéro dans ce cas, le résultat est une liste vide:
take6 n (b:bs) | n <= 0 = []
, mais il y a aussi un cas où n > 0
. Dans ce cas, nous voulons en effet préfixer b
au take6 (n-1) bs
. L'esprit cependant que d'une manière plus efficace de préfixer, est de nouveau à l'aide du constructeur « cons »:
ou en totalité:
take6 :: Int -> [a] -> [a]
take6 _ [] = []
take6 n (b:bs) | n <= 0 = []
| otherwise = b : take6 (n-1) bs
Oui, ce peut-être plus efficace. Mais lorsque GHC est exécuté avec des optimisations activées, elles doivent être identiques. Je n'ai pas vérifié cet exemple, mais il existe des règles spéciales pour désosser des listes littérales dans des formes 'build' qui devraient fusionner avec la forme' foldr' dans '(++)'. Dans ce cas, il ne sert à rien de se fier à cette optimisation, mais je soupçonne qu'il est plus important d'utiliser '[a]' comme cible monoid d'un foldMap. – dfeuer