เช่นเดียวกับชื่อเรื่อง: สิ่งใดที่รับประกันว่าจะมีการประเมินฟังก์ชั่นการส่งคืนหน่วย 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_correct
N ใน 1..6 หรือ 7 ซึ่งแต่ละหน่วยส่งคืนหากโครงสร้างถูกต้องแน่นอนและโยนข้อยกเว้นถ้าไม่ใช่ . นอกจากนี้ฟังก์ชั่นเหล่านี้เรียกว่ากันและกันเมื่อพวกเขาย่อยสลายเงื่อนไขความถูกต้อง ใน Haskell สิ่งนี้จัดการได้ดีกว่าการใช้Either String
monad ดังนั้นฉันจึงถอดความมันแบบนั้น แต่คำถามที่เป็นประเด็นทางทฤษฎียังคงอยู่ ขอบคุณสำหรับอินพุตและคำตอบทั้งหมด
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)
เท่านั้น