ทำไม Haskell ไม่สามารถหลีกเลี่ยงการประเมินซ้ำ ๆ โดยไม่มีข้อ จำกัด monomorphism


14

ฉันเพิ่งเสร็จสิ้นlearnyouahaskellวันอื่น ๆ และผมก็พยายามที่จะทำให้ความรู้สึกของข้อ จำกัด Monomorphism, ตามที่อธิบายไว้โดย Haskell วิกิพีเดีย ฉันคิดว่าฉันเข้าใจว่า MR สามารถป้องกันการประเมินซ้ำ ๆ ได้อย่างไร แต่ฉันล้มเหลวที่จะดูว่าทำไมการประเมินซ้ำ ๆ เหล่านั้นไม่สามารถหลีกเลี่ยงได้โดยวิธีที่ตรงไปตรงมามากขึ้น

ตัวอย่างที่ฉันมีอยู่ในใจคือตัวอย่างที่ใช้โดยวิกิ:

f xs = (len,len)
  where
    len = genericLength xs

ที่เป็นประเภทgenericLengthNum a => [b] -> a

เห็นได้ชัดว่าgenericLength xsต้องมีการคำนวณเพียงครั้งเดียวเพื่อประเมิน(len,len)เนื่องจากเป็นฟังก์ชันเดียวกันกับอาร์กิวเมนต์ที่เหมือนกัน และเราไม่จำเป็นต้องเห็นการเรียกร้องใด ๆfให้รู้ ดังนั้นทำไม Haskell ไม่สามารถทำการเพิ่มประสิทธิภาพนี้โดยไม่แนะนำกฎเช่น MR?

การอภิปรายในหน้าวิกินั้นบอกฉันว่ามีบางอย่างเกี่ยวกับความจริงที่ว่าNumเป็น typeclass มากกว่าประเภทที่เป็นรูปธรรม แต่ถึงกระนั้นก็ไม่ควรที่จะรวบรวมไว้ในเวลาที่ฟังก์ชั่น pure จะคืนค่าเดิม - - และดังนั้นประเภทคอนกรีตเดียวกันของ Num - เมื่อได้รับอาร์กิวเมนต์เดียวกันสองครั้ง

คำตอบ:


11

มันเป็นชื่อฟังก์ชั่นเดียวกันโดยมีอาร์กิวเมนต์เดียวกัน แต่อาจมีชนิดและการนำไปใช้งานที่แตกต่างกันออกไปเนื่องจากเป็น polymorphic ซึ่งหมายความว่าถ้ามันเรียกว่าในบริบทคาดหวังว่า(Int, MyWeirdCustomNumType)ผลตอบแทนประเภทก็มีการประเมินครั้งที่สองเพราะการดำเนินการ(+)ในการIntเป็นสมบูรณ์แตกต่างจากการดำเนินการใน(+) MyWeirdCustomNumTypeคุณจำเป็นต้องเรียกใช้รหัสที่แตกต่างกันทางกายภาพในบางจุด

นั่นเป็นเหตุผลว่าทำไมมันถึงNumเป็นคลาสแบบนั้น หมายความว่าคุณมีการใช้งานที่แตกต่างกันสำหรับประเภทที่แตกต่างกัน นอกจากนี้ยังหมายความว่าถ้าfอยู่ในไลบรารีจะไม่ทราบเวลารวบรวมเกี่ยวกับชุดค่าผสมทั้งหมดที่อาจต้องส่งคืน

ดังนั้นใช่คุณต้องดูการเรียกร้องfให้รู้ว่าจะใช้ประเภทการส่งคืนชนิดใด ส่วนใหญ่คุณคาดว่าพวกเขาจะเหมือนกันซึ่งเป็นเหตุผลที่พวกเขาวางข้อ จำกัด monomorphism ตามค่าเริ่มต้น มันสามารถปิดได้สำหรับโอกาสที่หายากเหล่านั้นเมื่อคุณทำไม่ได้ ในทางปฏิบัติโปรแกรมเมอร์ไม่น่าจะทิ้งสถานการณ์ประเภทนี้ไว้เพื่ออนุมานได้


f [] :: (Int, Float)ผมไม่ได้รับการพิจารณาความเป็นไปได้ของ ตอนนี้มันสมเหตุสมผลดี ขอขอบคุณ.
Ixrec

1
It's the same function name, with the same arguments, but potentially different return types and implementations, because it's polymorphic.ฉันคิดว่าวิธีที่ดีกว่าในการดูคืออินสแตนซ์ของประเภท typeclass เป็นอาร์กิวเมนต์พิเศษอย่างมีประสิทธิภาพgenericLengthและคอมไพเลอร์ไม่เชื่อว่ามันเป็นอาร์กิวเมนต์เดียวกันในการโทรทั้งสอง
Doval

คำถามด้านด่วน หาก MonomorphismRestriction ถูกปิด แต่หลังจากนั้นคุณทำสิ่งที่ชอบa = uncurry (==) $ f [1, 2, 3]มันจะสามารถเพิ่มประสิทธิภาพไซต์การโทรนั้นเพื่อตรวจสอบความยาว[1, 2, 3]เพียงครั้งเดียวหรือไม่? ถ้างั้นฉันก็สับสนจริง ๆ ว่าข้อ จำกัด monomorphism นั้นกำลังซื้อคุณจริงหรือไม่ถ้าอย่างนั้นทำไมไม่เป็นเช่นนั้น?
เซมิโคลอน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.