หากคุณกำลังมองหาการอ้างอิงที่เป็นระเบียบและใช้งานได้กับการอนุมานประเภทฉันมีบางส่วนเกี่ยวกับ Gundry, McBride และ McKinna ในปี 2010 " การอนุมานในบริบท " ของ McKinna แม้ว่านี่อาจไม่ใช่แนวทางที่ดีในการนำไปใช้จริง .
ฉันคิดว่าส่วนหนึ่งของคำตอบก็คือนอกเหนือจากข้อ จำกัด ด้านคุณค่าแล้วมันมีความยากลำบากไม่มากที่จะปรับการอนุมานประเภท Hindley-Milner เป็นภาษาที่จำเป็น: ถ้าคุณกำหนดe1; e2
ว่าน้ำตาล syntactic สำหรับ(fn _ => e2) e1
และกำหนดwhile e1 do e2
เป็นน้ำตาล syntactic สำหรับwhiledo e1 (fn () => e2)
ซึ่งwhiledo
เป็นปกติ ฟังก์ชั่นซ้ำ
fun whiledo g f = if g then (f (); whiledo g f) else ();
จากนั้นทุกอย่างจะทำงานได้ดีรวมถึงการอนุมานประเภท
สำหรับข้อ จำกัด ด้านมูลค่าเป็นเทคนิคพิเศษฉันชอบเรื่องราวต่อไปนี้ ฉันค่อนข้างแน่ใจว่าฉันหยิบมันมาจาก Karl Crary พิจารณารหัสต่อไปนี้ซึ่งการ จำกัด ค่าจะป้องกันคุณจากการเขียนใน ML:
let
val x: 'a option ref = ref NONE
in
(x := SOME 5; x := SOME "Hello")
end
เปรียบเทียบกับรหัสต่อไปนี้ซึ่งไม่มีปัญหาโดยสิ้นเชิง:
let
val x: unit -> 'a option ref = fn () => ref NONE
in
(x () := SOME 5; x () := SOME "Hello")
end
เรารู้ว่าตัวอย่างที่สองทำอะไร: มันสร้างเซลล์อ้างอิงใหม่สองเซลล์ที่มีอยู่NONE
จากนั้นใส่เซลล์SOME 5
แรก (หนึ่งint option ref
) จากนั้นใส่เซลล์ที่SOME "Hello"
สอง (หนึ่งstring option ref
)
x
x
∀α.ref(option(α))x
Λ อัลฟ่า อ้าง[α](NONE)
สิ่งนี้จะแนะนำว่าพฤติกรรม "ดี" ของตัวอย่างแรกคือการทำงานในลักษณะเดียวกับตัวอย่างที่สอง - ยกตัวอย่างแลมบ์ดาระดับประเภทสองครั้งที่แตกต่างกัน ครั้งแรกที่เรายกตัวอย่างx
ด้วยint
ซึ่งจะทำให้x [int]
ในการประเมินการถือครองเซลล์อ้างอิงแล้วNONE
SOME 5
เป็นครั้งที่สองที่เรายกตัวอย่างx
ด้วยstring
ซึ่งจะเป็นกรณีที่x [string]
ในการประเมินไป ( ! ที่แตกต่างกัน ) โฮลดิ้งถืออ้างอิงแล้วNONE
SOME "Hello"
ลักษณะการทำงานนี้ "ถูกต้อง" (ชนิดปลอดภัย) แต่ไม่ใช่สิ่งที่โปรแกรมเมอร์คาดหวังและนี่คือสาเหตุที่เรามีข้อ จำกัด ค่าใน ML เพื่อหลีกเลี่ยงโปรแกรมเมอร์ที่จัดการกับพฤติกรรมที่ไม่คาดคิดนี้
let val x = ref 9 in while !x>0 do (print (Int.toString (!x)); x := !x-1) end
) ดังนั้นในระดับของคำถามการวิจัยคำตอบที่คุณกำลังมองหาคือ "ใช้เทคนิคที่พัฒนาขึ้นใน Caml / SML รวมถึงข้อ จำกัด ของค่า"