ดูคำตอบ StackOverflowนี้เกี่ยวกับการอนุมานประเภทของ Go ฉันไม่คุ้นเคยกับตัวเองไป แต่ขึ้นอยู่กับคำตอบนี้ดูเหมือนว่า "การลดประเภท" แบบทางเดียว (เพื่อยืมบาง C ++ teminology) หมายความว่าถ้าคุณมี:
x := y + z
จากนั้นประเภทของการxอนุมานโดยการหาประเภทของy + zซึ่งเป็นสิ่งที่ค่อนข้างน่าสนใจสำหรับคอมไพเลอร์ ในการทำเช่นนี้ประเภทของyและzจำเป็นต้องรู้ก่อน : สามารถทำได้ผ่านคำอธิบายประกอบประเภทหรืออนุมานจากตัวอักษรที่กำหนดให้พวกเขา
ในทางตรงกันข้ามภาษาที่ใช้งานได้ส่วนใหญ่มีการอนุมานประเภทที่ใช้ข้อมูลที่เป็นไปได้ทั้งหมดภายในโมดูล (หรือฟังก์ชั่นหากอัลกอริทึมการอนุมานเป็นแบบโลคัล) เพื่อรับประเภทของตัวแปร อัลกอริธึมการอนุมานที่ซับซ้อน (เช่น Hindley-Milner) มักจะเกี่ยวข้องกับรูปแบบการรวมกันบางประเภท(เล็กน้อยเช่นการแก้สมการ) ที่อยู่เบื้องหลัง ตัวอย่างเช่นใน Haskell ถ้าคุณเขียน:
let x = y + z
แล้ว Haskell สามารถอนุมานชนิดไม่เพียงxแต่ยังyและzอยู่บนพื้นฐานของความเป็นจริงเพียงว่าคุณมีประสิทธิภาพนอกจากนี้ในพวกเขา ในกรณีนี้:
x :: Num a => a
y :: Num a => a
z :: Num a => a
(ตัวพิมพ์เล็กaที่นี่หมายถึงประเภท polymorphicมักจะเรียกว่า "generics" ในภาษาอื่นเช่น C ++ Num a =>ส่วนที่เป็นข้อ จำกัดเพื่อระบุว่าการaสนับสนุนประเภทมีความคิดบางอย่างของการเพิ่ม)
นี่คือตัวอย่างที่น่าสนใจมากขึ้น: combinator แบบคงที่ที่อนุญาตให้ฟังก์ชัน recursive ใด ๆ ถูกกำหนด:
let fix f = f (fix f)
ขอให้สังเกตว่าเราไม่ได้ระบุประเภทของfหรือไม่ได้ระบุประเภทของfixแต่คอมไพเลอร์ Haskell สามารถคิดได้โดยอัตโนมัติว่า:
f :: t -> t
fix :: (t -> t) -> t
สิ่งนี้บอกว่า:
- พารามิเตอร์
fต้องมีฟังก์ชั่นจากชนิดโดยพลบางชนิดเดียวกันtt
fixเป็นฟังก์ชั่นที่ได้รับพารามิเตอร์ของชนิดและผลตอบแทนที่เป็นผลมาจากประเภทt -> tt
x,y,zจะเหมือนกันNumประเภท eric แต่พวกเขายังคงสามารถIntegers,Doubles,Ratio Integers ... Haskell ยินดีที่จะให้เป็นตัวเลือกโดยพลระหว่างชนิดของตัวเลข แต่ไม่ได้สำหรับ typeclasses อื่น ๆ