68 votes

Que sont les "modèles n + k" et pourquoi sont-ils bannis de Haskell 2010?

En lisant l'entrée de Wikipedia sur Haskell 2010, je suis tombé sur ceci:

 -- using only prefix notation and n+k-patterns (no longer allowed in Haskell 2010)
factorial 0 = 1
factorial (n+1) = (*) (n+1) (factorial n)
 

Que veulent-ils dire par "motifs n + k"? Je suppose que c'est la deuxième ligne, mais je ne comprends pas ce qui pourrait ne pas être mal avec cela. Quelqu'un pourrait-il expliquer quel est le problème?

71voto

Quelles sont n+k modèles? Jetez un coup d'œil à ceci:

$ ghci
GHCi, version 6.12.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> let f 0 = 0 ; f (n+5) = n
Prelude> :t f
f :: (Integral t) => t -> t
Prelude> f 0
0
Prelude> f 1
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f

Prelude> f 2
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f

Prelude> f 3
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f

Prelude> f 4
*** Exception: <interactive>:1:4-24: Non-exhaustive patterns in function f

Prelude> f 5
0
Prelude> f 6
1

Ils sont fondamentalement extrêmement cas spécial sur la correspondance de modèle qui ne fonctionne que sur des nombres et qui ne sont ... eh bien, disons juste d'être poli et de l'appeler "des choses inattendues" de ces nombres.

Ici, j'ai une fonction f qui a deux clauses. Le premier alinéa de l'matchs 0 et seulement 0. La deuxième clause correspond à la valeur de type Intégral dont la valeur est de 5 ou plus. Le nom lié (n, dans ce cas) a une valeur égale au numéro que vous avez passé au moins 5. Pourquoi ils ont été supprimés à partir de Haskell 2010, j'espère que vous pouvez voir la raison maintenant, avec juste un peu de réflexion. (Indication: considérer le "principe de moindre surprise", et comment il peut ou peut ne pas s'appliquer ici.)


Edité pour ajouter:

Une question naturelle est de se posent maintenant que ces constructions sont interdites est "qu'utilisez-vous pour les remplacer?"

$ ghci
GHCi, version 6.12.3: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude> let f 0 = 0 ; f n | n >= 5 = n - 5
Prelude> :t f
f :: (Num t, Ord t) => t -> t
Prelude> f 0
0
Prelude> f 1
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f

Prelude> f 2
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f

Prelude> f 3
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f

Prelude> f 4
*** Exception: <interactive>:1:4-33: Non-exhaustive patterns in function f

Prelude> f 5
0
Prelude> f 6
1

Vous remarquerez à partir du type de déclarations que ce ne sont pas exactement égaux, mais l'utilisation d'un garde est "assez égal". L'utilisation de l' n-5 dans l'expression pourrait s'avérer fastidieuse et source d'erreurs dans le code qui utilise en plus d'un endroit. La réponse serait d'utiliser un where clause le long des lignes de cette:

Prelude> let f 0 = 0 ; f n | n >= 5 = n' where n' = n - 5
Prelude> :t f
f :: (Num t, Ord t) => t -> t
Prelude> f 0
0
Prelude> f 5
0
Prelude> f 6
1

L' where clause vous permet d'utiliser l'expression calculée en plusieurs endroits sans risque d'erreur de frappe. Il y a encore de la gêne d'avoir à modifier la valeur limite (5 dans ce cas) dans deux endroits différents dans la définition de la fonction, mais personnellement, je pense que c'est un petit prix à payer pour l'augmentation cognitive de la compréhension.


En outre modifié pour ajouter:

Si vous préférez let expressions plus de where clauses, c'est une alternative:

Prelude> let f 0 = 0 ; f n | n >= 5 = let n' = n - 5 in n'
Prelude> :t f
f :: (Num t, Ord t) => t -> t
Prelude> f 0
0
Prelude> f 5
0

Et c'est tout. Je suis vraiment fait maintenant.

4voto

perimosocordiae Points 4582

Le lien fourni par trinithis est correct; Les motifs n + k ne sont plus inclus dans les spécifications Haskell.

Pour plus d’informations sur les motifs n + k en général, faites défiler cette page jusqu’à 3 / 5ème de la page pour rechercher les correspondances , ou consultez ce court article .

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