ฉันใหม่เพื่อ Haskell และฉันสับสนมากจากไหนเมื่อเทียบกับLet ดูเหมือนทั้งสองจะมีจุดประสงค์ที่คล้ายกัน ฉันได้อ่านการเปรียบเทียบเล็กน้อยระหว่างWhereกับLetแต่ฉันมีปัญหาในการแยกแยะว่าเมื่อใดควรใช้ ใครช่วยกรุณาให้บริบทบางอย่างหรืออาจเป็นตัวอย่างบางส่วนที่แสดงให้เห็นว่าเมื่อใดควรใช้อย่างอื่น
ที่ไหนเทียบกับ
whereประโยคสามารถกำหนดเฉพาะในระดับของการกำหนดฟังก์ชั่น โดยปกติแล้วจะเหมือนกับขอบเขตของletคำจำกัดความ ความแตกต่างเพียงอย่างเดียวคือเมื่อยามที่มีการใช้ ขอบเขตของwhereประโยคขยายครอบคลุมยามทั้งหมด ในทางตรงกันข้ามขอบเขตของletนิพจน์เป็นเพียงประโยคฟังก์ชันปัจจุบันและตัวป้องกันถ้ามี
Haskell วิกิพีเดียมีรายละเอียดมากและให้หลาย ๆ กรณี แต่จะใช้ตัวอย่างสมมุติ ฉันพบว่าคำอธิบายสั้นเกินไปสำหรับผู้เริ่มต้น
ข้อดีของการให้ :
f :: State s a
f = State $ \x -> y
   where y = ... x ...จะไม่ทำงานเนื่องจากโดยที่อ้างถึงรูปแบบที่ตรงกับ f = โดยที่ x ไม่อยู่ในขอบเขต ในทางตรงกันข้ามถ้าคุณเริ่มต้นด้วยการปล่อยให้คุณก็จะไม่มีปัญหา
Haskell Wiki เกี่ยวกับข้อดีของการให้
f :: State s a
f = State $ \x ->
   let y = ... x ...
   in  yข้อดีของที่ไหน :
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)วิกิฮาสเคลกล่าวว่าประโยคWhereถูกประกาศในขณะที่นิพจน์Letเป็นการแสดงออก นอกเหนือจากสไตล์แล้วพวกเขาทำงานแตกต่างกันอย่างไร?
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 ...- ในตัวอย่างแรกเหตุใดLet จึงอยู่ในขอบเขต แต่ไม่อยู่ที่ไหน
- เป็นไปได้ไหมที่จะใช้Whereกับตัวอย่างแรก
- บางคนสามารถใช้สิ่งนี้กับตัวอย่างจริงที่ตัวแปรแสดงถึงนิพจน์จริงได้หรือไม่?
- มีกฎทั่วไปที่ต้องปฏิบัติตามเมื่อใช้แต่ละข้อหรือไม่?
ปรับปรุง
สำหรับผู้ที่มาจากหัวข้อนี้ในภายหลังฉันพบคำอธิบายที่ดีที่สุดที่นี่: " A Gentle Introduction to Haskell "
ให้นิพจน์
นิพจน์ let ของ Haskell มีประโยชน์เมื่อใดก็ตามที่จำเป็นต้องใช้ชุดการผูกที่ซ้อนกัน เป็นตัวอย่างง่ายๆให้พิจารณา:
let y = a*b f x = (x+y)/y in f c + f dชุดของการผูกที่สร้างขึ้นโดยนิพจน์ let นั้นเป็นแบบวนซ้ำร่วมกันและการผูกรูปแบบจะถือว่าเป็นรูปแบบที่ขี้เกียจ (กล่าวคือมีนัย ~) การประกาศประเภทเดียวที่อนุญาตคือลายเซ็นประเภทการผูกฟังก์ชันและการผูกรูปแบบ
ที่ข้อ
บางครั้งมันก็สะดวกในการกำหนดขอบเขตการผูกกับสมการที่มีการป้องกันหลาย ๆ อย่างซึ่งต้องใช้คำสั่ง where:
f x y | y>z = ... | y==z = ... | y<z = ... where z = x*xโปรดทราบว่าสิ่งนี้ไม่สามารถทำได้ด้วยนิพจน์ let ซึ่งขอบเขตเหนือนิพจน์ที่ล้อมรอบเท่านั้น โดยที่อนุประโยคได้รับอนุญาตที่ระดับบนสุดของชุดสมการหรือนิพจน์กรณีเท่านั้น คุณสมบัติและข้อ จำกัด เดียวกันในการผูกในนิพจน์ let ใช้กับคุณสมบัติที่อยู่ในส่วนคำสั่ง ขอบเขตที่ซ้อนกันทั้งสองรูปแบบนี้ดูคล้ายกันมาก แต่จำไว้ว่านิพจน์ let เป็นนิพจน์ในขณะที่ส่วนคำสั่งไม่ใช่ - เป็นส่วนหนึ่งของไวยากรณ์ของการประกาศฟังก์ชันและนิพจน์กรณี
f = body where x = xbody; y = ybody ...หมายถึงf = let x = xbody; y = ybody ... in body
                case .... of ... whereนิพจน์ได้หรือไม่? ฉันไม่แน่ใจเกี่ยวกับเรื่องนี้
                
letและwhereเมื่อฉันเริ่มเรียนรู้ Haskell ครั้งแรก ฉันคิดว่าวิธีที่ดีที่สุดในการทำความเข้าใจคือการตระหนักว่าทั้งสองมีความแตกต่างกันเล็กน้อยดังนั้นจึงไม่มีอะไรต้องกังวล ความหมายของการwhereให้ในแง่ของletการแปลงทางกลที่เรียบง่ายมาก ดูhaskell.org/onlinereport/decls.html#sect4.4.3.2 การ เปลี่ยนแปลงนี้มีขึ้นเพื่อความสะดวกในการระบุเท่านั้นจริงๆ