ดูคำตอบ 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
ต้องมีฟังก์ชั่นจากชนิดโดยพลบางชนิดเดียวกันt
t
fix
เป็นฟังก์ชั่นที่ได้รับพารามิเตอร์ของชนิดและผลตอบแทนที่เป็นผลมาจากประเภทt -> t
t
x
,y
,z
จะเหมือนกันNum
ประเภท eric แต่พวกเขายังคงสามารถInteger
s,Double
s,Ratio Integer
s ... Haskell ยินดีที่จะให้เป็นตัวเลือกโดยพลระหว่างชนิดของตัวเลข แต่ไม่ได้สำหรับ typeclasses อื่น ๆ