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.