เช่นเดียวกับชื่อเรื่อง: สิ่งใดที่รับประกันว่าจะมีการประเมินฟังก์ชั่นการส่งคืนหน่วย Haskell? ใครจะคิดว่าไม่จำเป็นต้องเรียกใช้การประเมินผลใด ๆ ในกรณีเช่นนี้คอมไพเลอร์สามารถแทนที่การเรียกเช่นนั้นทั้งหมดด้วย()ค่าทันทีเว้นแต่จะมีการร้องขออย่างชัดเจนสำหรับความเข้มงวดที่มีอยู่ในกรณีนี้รหัสอาจต้องตัดสินใจว่าควร กลับ()หรือด้านล่าง
ฉันได้ทดลองสิ่งนี้ใน GHCi และดูเหมือนว่าสิ่งตรงกันข้ามเกิดขึ้นนั่นคือฟังก์ชั่นดังกล่าวจะได้รับการประเมิน ตัวอย่างดั้งเดิมมากจะเป็น
f :: a -> ()
f _ = undefined
การประเมินf 1ข้อผิดพลาดเกิดขึ้นเนื่องจากการปรากฏตัวของundefinedดังนั้นการประเมินผลบางอย่างเกิดขึ้นแน่นอน แม้ว่าจะยังไม่ชัดเจนว่าการประเมินจะเกิดขึ้นในระดับใด ()บางครั้งก็ดูเหมือนจะเป็นไปตามที่ลึกที่สุดเท่าที่มันเป็นสิ่งจำเป็นในการประเมินทุกสายฟังก์ชั่นกลับมา ตัวอย่าง:
g :: [a] -> ()
g [] = ()
g (_:xs) = g xs
รหัสนี้จะวนg (let x = 1:x in x)ซ้ำไปเรื่อย ๆ หากแสดงด้วย แต่แล้ว
f :: a -> ()
f _ = undefined
h :: a -> ()
h _ = ()
สามารถใช้เพื่อแสดงh (f 1)ผลตอบแทน()ได้ดังนั้นในกรณีนี้ไม่ได้ประเมิน subexpressions ที่มีค่าหน่วยทั้งหมด กฎทั่วไปที่นี่คืออะไร?
การทางพิเศษแห่งประเทศไทย: แน่นอนฉันรู้เกี่ยวกับความเกียจคร้าน ฉันถามสิ่งที่ป้องกันไม่ให้นักเขียนคอมไพเลอร์ทำให้กรณีนี้แม้แต่ขี้เกียจกว่าปกติ
ETA2: สรุปตัวอย่าง: GHC ดูเหมือนจะปฏิบัติ()เหมือนกับประเภทอื่น ๆ ทุกประการเช่นราวกับว่ามีคำถามเกี่ยวกับค่าปกติที่พำนักอยู่ควรส่งคืนประเภทจากฟังก์ชัน ความจริงที่ว่ามีเพียงหนึ่งค่าดังกล่าวดูเหมือนจะไม่ (ab) ใช้โดยอัลกอริทึมการเพิ่มประสิทธิภาพ
ETA3: เมื่อฉันพูด Haskell ฉันหมายถึง Haskell ตามที่กำหนดโดยรายงานไม่ใช่ Haskell-the-H-in-GHC ดูเหมือนว่าจะเป็นสมมติฐานที่ไม่ได้แชร์กันอย่างกว้างขวางเท่าที่ฉันจินตนาการ (ซึ่งเป็น '100% ของผู้อ่าน') หรือฉันอาจจะสามารถตั้งคำถามที่ชัดเจนขึ้นได้ ถึงกระนั้นฉันก็เสียใจที่เปลี่ยนชื่อของคำถามเพราะเดิมทีมันถามว่ามีการรับประกันอะไรสำหรับฟังก์ชั่นดังกล่าว
ETA4: ดูเหมือนว่าคำถามนี้ได้เริ่มต้นขึ้นแล้วและฉันคิดว่ามันยังไม่ได้ตอบ (ฉันกำลังมองหาฟังก์ชั่น 'คำถามที่ปิด' แต่พบเพียง 'ตอบคำถามของคุณเอง' และเนื่องจากไม่สามารถตอบได้ฉันไม่ได้ลงไปตามเส้นทางนั้น) ไม่มีใครนำสิ่งใดมาจากรายงานที่จะตัดสินใจด้วยวิธีใด ซึ่งฉันถูกล่อลวงให้ตีความว่าเป็นคำที่แข็งแกร่ง แต่ไม่แน่นอนว่า 'ไม่รับประกันสำหรับภาษาดังกล่าว' คำตอบ สิ่งที่เรารู้คือการใช้ GHC ปัจจุบันจะไม่ข้ามการประเมินฟังก์ชั่นดังกล่าว
ฉันพบปัญหาจริงเมื่อทำการย้ายแอป OCaml ไปยัง Haskell แอปดั้งเดิมมีโครงสร้างแบบเรียกซ้ำหลายชนิดและรหัสประกาศฟังก์ชันที่เรียกว่าassert_structureN_is_correctN ใน 1..6 หรือ 7 ซึ่งแต่ละหน่วยส่งคืนหากโครงสร้างถูกต้องแน่นอนและโยนข้อยกเว้นถ้าไม่ใช่ . นอกจากนี้ฟังก์ชั่นเหล่านี้เรียกว่ากันและกันเมื่อพวกเขาย่อยสลายเงื่อนไขความถูกต้อง ใน Haskell สิ่งนี้จัดการได้ดีกว่าการใช้Either Stringmonad ดังนั้นฉันจึงถอดความมันแบบนั้น แต่คำถามที่เป็นประเด็นทางทฤษฎียังคงอยู่ ขอบคุณสำหรับอินพุตและคำตอบทั้งหมด
f 1คือ "แทนที่" โดยundefinedในทุกกรณี
... -> ()สามารถ 1) ยุติและส่งคืน()2) ยุติด้วยข้อผิดพลาดข้อยกเว้น / runtime และล้มเหลวที่จะกลับอะไรหรือ 3) diverge (เรียกซ้ำไม่สิ้นสุด) GHC ไม่ได้เพิ่มประสิทธิภาพของรหัสสมมติเพียง 1) สามารถเกิดขึ้นได้ถ้ามีการเรียกร้องก็ไม่ได้ข้ามการประเมินผลและการกลับมาของf 1 ()ความหมายของ Haskell คือการประเมินและดูว่าเกิดอะไรขึ้นกับ 1,2,3
()(ประเภทหรือค่า) ในคำถามนี้ ข้อสังเกตเดียวกันทั้งหมดเกิดขึ้นหากคุณแทนที่() :: ()พูด0 :: Intทุกที่ สิ่งเหล่านี้ล้วน แต่น่าเบื่อที่จะตามมาจากการประเมินที่ขี้เกียจ
()ชนิดและ() undefined
h1::()->() ; h1 () = ()h2::()->() ; h2 _ = ()เรียกใช้ทั้งสองh1 (f 1)และh2 (f 1)และดูว่ามีเพียงความต้องการแรก(f 1)เท่านั้น