Ils diffèrent par leur rigueur. Supposons que nous rebaptiser eux
> let addVectorsStrict (x1, y1) (x2, y2) = (x1 + x2, y1 + y2)
> let addVectorsLazy a b = (fst a + fst b, snd a + snd b)
addVectorsStrict undefined undefined
est undefined
-la correspondance de motif est réalisé dès que le constructeur (,)
externe du résultat est exigé:
> case addVectorsStrict (error "A") (error "B") of (_, _) ->()
*** Exception: A
Mais addVectorsLazy undefined undefined
est (undefined, undefined)
-le pattern matching est différé jusqu'à ce que l'un des éléments du résultat soit demandé.
> case addVectorsLazy (error "A") (error "B") of (_, _) ->()
()
Fondamentalement, addVectorsLazy
retourne toujours un tuple, où les éléments peuvent être évaluées. addVectorsStrict
peut ne pas retourner. Vous pouvez également obtenir l'effet de addVectorsLazy
en utilisant une correspondance de motif paresseux:
> let addVectorsAlsoLazy ~(x1, y1) ~(x2, y2) = (x1 + x2, y1 + y2)
> case addVectorsAlsoLazy (error "A") (error "B") of (_, _) ->()
()
Pour obtenir une meilleure compréhension de l'ordre d'évaluation, vous pouvez l'observer à l'aide Debug.Trace.trace
:
addVectors
(trace "first tuple evaluated"
(trace "x1 evaluated" 1, trace "y1 evaluated" 2))
(trace "second tuple evaluated"
(trace "x2 evaluated" 3, trace "y2 evaluated" 4))
La chose fondamentale à retenir au sujet L'évaluation dans Haskell est qu'elle est conduite par la correspondance de modèle en utilisant case
et les équations de fonction (qui vont de case
).
Il n'a pas beaucoup d'importance dans ce cas, mais vous pouvez écrire vos fonctions paresseusement pour éviter l'évaluation des calculs coûteux si leurs résultats ne sont jamais nécessaires ou strictement pour éviter la surcharge de thunks si vous connaissez un résultat sera toujours être nécessaire.
En général, il est une bonne idée de faire les champs de vos structures de données stricte à moins que vous en avez besoin d'être paresseux et faire vos fonctions paresseux à moins que vous devez être stricte. Ici vous pouvez faire un type de paire strict pour représenter vos vecteurs:
data Vector a = Vector !a !a
Eh bien, c'est juste un style différent de définir la même chose. Quelle est exactement votre question? – leftaroundabout
En guise de conseil général, je recommande d'apprendre à utiliser autant que possible le pattern matching, au moins au niveau débutant.L'alternative avec 'fst, snd' est OK, mais ici sur SO j'ai vu trop de débutants pour utiliser des fonctions dangereuses comme' head, tail, fromJust', qui conduisent souvent à des crashs, quand le pattern matching est beaucoup plus sûr, surtout quand les avertissements sont activés avec '-Wall' (fortement recommandé). – chi