Je suis nouveau à Haskell et je suis très confus par Where vs. Let . Ils semblent tous deux avoir un objectif similaire. J'ai lu quelques comparaisons entre Where vs. Let mais j'ai du mal à discerner quand les utiliser. Quelqu'un pourrait-il fournir un contexte ou peut-être quelques exemples qui montrent quand utiliser l'un plutôt que l'autre?
Où vs laisser
Une
where
clause ne peut être définie qu'au niveau d'une définition de fonction. Habituellement, cela correspond à la portée de lalet
définition. La seule différence est lorsque des gardes sont utilisés . La portée de lawhere
clause s'étend à tous les gardiens. En revanche, la portée d'unelet
expression est uniquement la clause de fonction actuelle et la garde, le cas échéant.
Le Wiki Haskell est très détaillé et fournit divers cas mais il utilise des exemples hypothétiques. Je trouve ses explications trop brèves pour un débutant.
Avantages de Let :
f :: State s a
f = State $ \x -> y
where y = ... x ...
ne fonctionnera pas, car where se réfère au modèle correspondant à f =, où aucun x n'est dans la portée. En revanche, si vous aviez commencé avec let, vous n'auriez aucun problème.
Haskell Wiki sur les avantages de Let
f :: State s a
f = State $ \x ->
let y = ... x ...
in y
Avantages de Où :
f x
| cond1 x = a
| cond2 x = g a
| otherwise = f (h x a)
where
a = w x
f x
= let a = w x
in case () of
_ | cond1 x = a
| cond2 x = g a
| otherwise = f (h x a)
Le wiki Haskell mentionne que la clause Where est déclarative tandis que l' expression Let est expressive. Mis à part le style, comment fonctionnent-ils différemment?
Declaration style | Expression-style
--------------------------------------+---------------------------------------------
where clause | let expression
arguments LHS: f x = x*x | Lambda abstraction: f = \x -> x*x
Pattern matching: f [] = 0 | case expression: f xs = case xs of [] -> 0
Guards: f [x] | x>0 = 'a' | if expression: f [x] = if x>0 then 'a' else ...
- Dans le premier exemple, pourquoi le Let est-il dans la portée mais Où ne l'est pas?
- Est-il possible d'appliquer Où au premier exemple?
- Certains peuvent-ils appliquer cela à des exemples réels où les variables représentent des expressions réelles?
- Existe-t-il une règle générale à suivre pour utiliser chacun d'eux?
Mettre à jour
Pour ceux qui reviennent plus tard sur ce fil, j'ai trouvé la meilleure explication ici: " Une introduction douce à Haskell ".
Laissez Expressions.
Les expressions let de Haskell sont utiles chaque fois qu'un ensemble imbriqué de liaisons est requis. À titre d'exemple simple, considérons:
let y = a*b f x = (x+y)/y in f c + f d
L'ensemble des liaisons créées par une expression let est mutuellement récursive et les liaisons de motifs sont traitées comme des motifs paresseux (c'est-à-dire qu'elles portent un ~ implicite). Les seuls types de déclarations autorisés sont les signatures de type, les liaisons de fonction et les liaisons de modèle.
Où les clauses.
Parfois, il est pratique de définir des liaisons sur plusieurs équations protégées, ce qui nécessite une clause where:
f x y | y>z = ... | y==z = ... | y<z = ... where z = x*x
Notez que cela ne peut pas être fait avec une expression let, qui ne s'étend que sur l'expression qu'elle englobe. Une clause where n'est autorisée qu'au niveau supérieur d'un ensemble d'équations ou d'une expression de cas. Les mêmes propriétés et contraintes sur les liaisons dans les expressions let s'appliquent à celles des clauses where. Ces deux formes de portée imbriquée semblent très similaires, mais rappelez-vous qu'une expression let est une expression, alors qu'une clause where ne l'est pas - elle fait partie de la syntaxe des déclarations de fonction et des expressions case.
f = body where x = xbody; y = ybody ...
signifief = let x = xbody; y = ybody ... in body
case .... of ... where
expression d' une manière ou d' une autre? Je ne suis pas certain de cela.
let
etwhere
quand j'ai commencé à apprendre Haskell. Je pense que la meilleure façon de le comprendre est de se rendre compte qu'il y a très peu de différence entre les deux, et donc rien à craindre. Le sens duwhere
donné en termes delet
par une transformation mécanique très simple. Voir haskell.org/onlinereport/decls.html#sect4.4.3.2 Cette transformation existe uniquement à des fins de notation, en réalité.