Haskell'de yeniyim ve Where vs. Let ile kafam çok karışık . İkisi de benzer bir amaç sağlıyor gibi görünüyor. Nerede ve Let arasında birkaç karşılaştırma okudum ancak her birini ne zaman kullanacağımı ayırt etmekte güçlük çekiyorum. Biri lütfen bir bağlam veya belki birini diğerinin üzerine ne zaman kullanacağını gösteren birkaç örnek verebilir mi?
Let vs Let
Bir
where
yan tümce, yalnızca bir işlev tanımı düzeyinde tanımlanabilir. Genellikle bu,let
tanımın kapsamıyla aynıdır . Tek fark, korumaların kullanıldığı zamandır .where
Maddenin kapsamı tüm korumaları kapsar. Buna karşılık, birlet
ifadenin kapsamı , varsa, yalnızca geçerli işlev cümlesi ve korumadır.
Haskell Wiki çok detaylı ve çeşitli durumlarda sağlar ama varsayımsal örnekler kullanır. Yeni başlayanlar için açıklamalarını çok kısa buluyorum.
Let Avantajları :
f :: State s a
f = State $ \x -> y
where y = ... x ...
çalışmayacaktır, çünkü burada, kapsamda hiçbir x olmadığında, f = eşleme kalıbını ifade eder. Aksine, Let ile başlasaydın, o zaman sorun yaşamazdın.
Let Avantajları için Haskell Wiki
f :: State s a
f = State $ \x ->
let y = ... x ...
in y
Nerede Olmanın Avantajları :
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)
Haskell wiki , Let ifadesinin anlamlı iken Where cümlesinin bildirimsel olduğundan bahseder . Tarzın dışında nasıl farklı performans sergiliyorlar?
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 ...
- İlk örnekte izin ver neden kapsam dahilindedir ama nerede değildir?
- İlk örneğe nereye başvurmak mümkün mü ?
- Bazıları bunu değişkenlerin gerçek ifadeleri temsil ettiği gerçek örneklere uygulayabilir mi?
- Her birinin ne zaman kullanılacağına dair genel bir kural var mı?
Güncelleme
Bu konuya sonradan gelenler için en iyi açıklamayı burada buldum: " Haskell'e Nazik Bir Giriş ".
İfadeler edelim.
Haskell'in let ifadeleri, iç içe geçmiş bir dizi bağlama gerektiğinde kullanışlıdır. Basit bir örnek olarak şunları düşünün:
let y = a*b f x = (x+y)/y in f c + f d
Bir let ifadesi tarafından oluşturulan bağlar kümesi karşılıklı olarak özyinelemelidir ve desen bağlamaları tembel desenler olarak ele alınır (yani örtük bir ~ taşırlar). İzin verilen tek bildirim türü, tür imzaları, işlev bağlamaları ve desen bağlamalarıdır.
Cümleler nerede.
Bazen, bir where cümlesi gerektiren birkaç korumalı denklem üzerinden bağlamaların kapsamını almak uygundur:
f x y | y>z = ... | y==z = ... | y<z = ... where z = x*x
Bunun, yalnızca içerdiği ifadeyi kapsayan bir let ifadesi ile yapılamayacağına dikkat edin. Where cümlesine yalnızca bir dizi denklemin veya durum ifadesinin en üst düzeyinde izin verilir. Let ifadelerindeki bağlamalarla ilgili aynı özellikler ve kısıtlamalar where cümleleri için de geçerlidir. Bu iki iç içe geçmiş kapsam biçimi çok benzer görünür, ancak let ifadesinin bir ifade olduğunu, oysa bir where cümlesinin olmadığını unutmayın - işlev bildirimleri ve durum ifadelerinin sözdiziminin bir parçasıdır.
f = body where x = xbody; y = ybody ...
meanf = let x = xbody; y = ybody ... in body
case .... of ... where
şekilde ifadeye dönüştürmek mümkün müdür ? Bunun hakkında emin değilim.
let
vewhere
ben ilk Haskell öğrenmeye başladı. Bence bunu anlamanın en iyi yolu, ikisi arasında çok az fark olduğunu ve bu nedenle endişelenecek bir şey olmadığını fark etmektir. Anlamıwhere
açısından verilenlet
çok basit bir mekanik dönüşüm yoluyla. Haskell.org/onlinereport/decls.html#sect4.4.3.2 adresine bakın . Bu dönüşüm yalnızca notasyonel kolaylık için var, gerçekten.