Якщо ви шукаєте акуратне, функціональне посилання на висновок про тип, я трохи частково ставлюся до "Виводу типу в контексті " Gundry, McBride та McKinna 2010 року , хоча це може бути не гарним посібником щодо будь-яких фактичних існуючих реалізацій .
Я думаю, що частина відповіді полягає в тому, що поза обмеженням значення, насправді не так вже й багато труднощів у адаптації висновку типу Хіндлі-Мілнера до імперативних мов: якщо ви визначаєте e1; e2як синтаксичний цукор (fn _ => e2) e1і визначаєте while e1 do e2як синтаксичний цукор для whiledo e1 (fn () => e2), де whiledoрегулярний рекурсивна функція
fun whiledo g f = if g then (f (); whiledo g f) else ();
тоді все буде добре, включаючи умовиводи.
Що стосується обмеження значення як особливої техніки, мені подобається наступна історія; Я майже впевнений, що взяв його у Карла Крарі. Розглянемо наступний код, обмеження значення якого не дозволить вам писати в 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
Ми знаємо, що робить другий приклад: він створює дві нові клітинки ref, що містять NONE, потім ставить SOME 5у першу (an int option ref), потім ставить SOME "Hello"у другу (a string option ref).
xx∀ α . ref ( варіант ( α ) )xΛ α . ref [ α ] ( 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, включаючи обмеження значення"?