การอนุมาน Hindley-Milner สามารถทำงานกับภาษา Go ได้หรือไม่


22

ฉันอ่านแล้วว่าHindley-Milnerไม่ทำงานกับระบบพิมพ์ที่มีคลาสย่อยและมีคุณสมบัติของระบบประเภทอื่น ๆ ที่ใช้งานไม่ได้กับมัน ไปในขณะนี้มีข้อสรุปประเภท จำกัด มากใน:=ผู้ประกอบการ แต่ Go ไม่ได้มี subclasses ในความหมายดั้งเดิมมีเพียงอินเตอร์เฟสที่มีลักษณะคล้ายกับคลาสของ Haskell ซึ่งทำงานได้ดีกับการอนุมาน Hindley-Milner

ดังนั้นการอนุมานของ Hindley-Milner สามารถทำงานได้ในหลักการของ Go แบบเดียวกับ Haskell หรือไม่? หรือไปมีคุณสมบัติอื่น ๆ ที่ทำลายมันได้หรือไม่ (ในทางกลับกัน Haskell ยังมีคุณสมบัติบางอย่างที่ไม่สามารถใช้กับ Hindly-Milner ได้หากคุณใช้สิ่งที่คุณต้องพิมพ์ด้วยตนเองในส่วนของโปรแกรม)

คำตอบ:


35

การอนุมานประเภท Hindley-Milner ใช้สำหรับระบบประเภท Hindley-Milner ซึ่งเป็นข้อ จำกัด ของระบบชนิด System-F คุณลักษณะที่น่าสนใจของ HM type systems คือพวกมันมีตัวแปรหลากหลาย (aka. generics) นั่นเป็นคุณลักษณะระบบที่ใหญ่ที่สุดเพียงอย่างเดียวที่ Golang ปฏิเสธ

ด้วยข้อ จำกัด ที่น่าผิดหวังการอนุมานประเภท HM เป็นไปไม่ได้ ลองดูโค้ดที่ไม่มีการพิมพ์:

func f(a) {
  return a.method()
}

ประเภทfใด เราอาจสังเกตเห็นว่าจะต้องมีวิธีการเพื่อให้เราสามารถใช้อินเตอร์เฟซที่ไม่ระบุชื่อ:a func f(a interface { method() ??? }) ???อย่างไรก็ตามเราไม่ทราบว่าประเภทการส่งคืนคืออะไร ด้วยตัวแปรประเภทเราสามารถประกาศประเภทเป็น

func f[T](a interface{ method() T }) T

อย่างไรก็ตาม Go ไม่มีตัวแปรประเภทดังนั้นสิ่งนี้จะไม่ทำงาน ในขณะที่อินเทอร์เฟซโดยนัยทำให้การอนุมานของลักษณะง่ายขึ้นตอนนี้เราไม่มีวิธีค้นหาชนิดส่งคืนของการเรียกฟังก์ชัน HM-system ต้องการฟังก์ชั่นทั้งหมดที่จะประกาศมากกว่าที่จะบอกเป็นนัยและแต่ละชื่อสามารถมีได้เพียงประเภทเดียวเท่านั้น

แต่ต้องใช้ฟังก์ชันนั้นในการประกาศอย่างเต็มที่ แต่อนุญาตให้ตัวแปรใช้การอนุมานประเภท สิ่งนี้เป็นไปได้เพราะทางด้านขวามือของการบ้านvariable := expressionมีประเภทที่ทราบแล้ว ณ จุดนั้นของโปรแกรม การอนุมานประเภทนี้เป็นแบบง่ายถูกต้องและเป็นเส้น

  • ชนิดของตัวแปรเป็นที่รู้จักกันทันที ณ จุดประกาศในขณะที่การอนุมาน HM จะต้องตรวจสอบโปรแกรมทั้งหมดก่อน สิ่งนี้มีผลกระทบต่อคุณภาพของข้อความแสดงข้อผิดพลาดเช่นกัน
  • วิธีการอนุมาน Type ของ Go จะเลือกชนิดที่เจาะจงที่สุดสำหรับตัวแปรเสมอซึ่งตรงกันข้ามกับ HM ที่เลือกประเภททั่วไปมากที่สุด สิ่งนี้ทำงานได้อย่างสมบูรณ์กับการพิมพ์ย่อยแม้จะมีอินเตอร์เฟสแบบนัยของ Go

24
@ บิชอปมันเป็น "เหตุผล" สำหรับค่า "เหตุผล" เล็กน้อยเล็ก ๆ น้อย ๆ
ฮอบส์

18
@ บิชอปหลังจากคอมไพเลอร์ทำงานในภาษาที่มีชื่อสามัญฉันสามารถเห็นด้วยอย่างแน่นอน: มันยากที่จะนำไปใช้ ฉันไปไกลถึงจะเปลี่ยน "ยาก" ด้วย "เป็นไปไม่ได้" อย่างไรก็ตามนั่นไม่ใช่ประเด็น; ประเด็นคือมันคุ้มค่ากับความซับซ้อนที่เพิ่มขึ้นไหม? และคำตอบสำหรับทุกคนที่ทำงานกับและไม่ใช้ยาทั่วไปเห็นได้ชัดว่า "ใช่แน่นอน!" ฉันต้องเห็นด้วยอย่างสุดใจกับคำกล่าวอ้างที่ปฏิเสธที่จะใช้ยาสามัญเพราะเพราะ "ไม่ซับซ้อน" เป็นเรื่องงี่เง่า
Mason Wheeler

18
นี่คือสาเหตุที่ผู้ที่หลงไหลไปทำท่าว่า FP ทุกประเภทไม่ดี ไปมีฟังก์ชั่นชั้นแรกกับการปิดคำศัพท์และมีความสามารถในการสร้างฟังก์ชั่นขั้นสูง แต่มันเป็นไปไม่ได้ที่จะนำพวกเขาไปใช้งานที่ดีใด ๆ เพราะชนิดของฟังก์ชั่นพื้นฐานเช่นmap, filterและreduceทั้งหมดที่อธิบายไม่ได้ภายในโก จำกัด มาก ระบบประเภท
ฮอบส์

9
@hobbs และไปอาจจะเป็นจริงๆภาษาที่ดีถ้าได้รับการแก้ไข แต่คนต้องเขียนห้องสมุดรุ่นทั่วไปเช่นgengenและgonerics
แมว

14
@cat มันน่าละอาย ในตอนแรกไปดูเหมือนว่าภาษาที่ยิ่งใหญ่ที่เต็มไปด้วยความคิดที่ดี แต่แล้วคุณก็รู้ว่ามันไม่มีการสืบทอดและความหลากหลายดังนั้นคุณจึงไม่สามารถทำ OOP ได้ดีและมันไม่มียาชื่อสามัญดังนั้นคุณจึงไม่สามารถทำ FP ได้ดีและ เหลือที่จ้องมองหน้าจออย่างว่างเปล่าถามว่า "ถ้าอย่างนั้นคุณควรใช้ภาษานี้ได้อย่างไร?!?"
Mason Wheeler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.