Может ли вывод Хиндли-Милнера работать на языке Go?

22

Я читал, что Хиндли-Милнер не работает с системами типов, которые имеют подклассы, и есть другие функции системы типов, которые также не работают с ним. Go в настоящее время имеет только очень ограниченный тип вывода в :=операторе. Но Go не имеет подклассов в традиционном смысле, только интерфейсы, которые очень похожи на классы типов Хаскелла, которые прекрасно работают с выводом Хиндли-Милнера.

Итак, может ли вывод Хиндли-Милнера работать в принципе так же, как и в Go, как в Haskell? Или у Go есть другие функции, которые его ломают? (С другой стороны, в Haskell также есть некоторые функции, которые не работают с Hindly-Milner, если вы используете те из них, которые вам приходится вводить вручную в эти части программы.)

JanKanis
источник

Ответы:

35

Вывод типа Хиндли-Милнера используется для систем типа Хиндли-Милнера, ограничение систем типа System-F. Интересной особенностью систем типа HM является то, что они имеют параметрический полиморфизм (он же дженерики). Это единственная особенность системы типов, которую Голанг отказывается иметь.

С этим разочаровывающим ограничением вывод типа HM невозможен. Давайте посмотрим на нетипизированный код:

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

Какой тип f? Мы могли бы заметить , что aдолжен иметь метод, чтобы мы могли использовать анонимный интерфейс: func f(a interface { method() ??? }) ???. Однако мы понятия не имеем, что такое тип возвращаемого значения. С переменными типа мы могли бы объявить тип как

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

Однако в Go нет переменных типа, поэтому это не сработает. Несмотря на то, что неявные интерфейсы облегчают некоторые аспекты вывода типов, у нас теперь нет возможности узнать тип возврата вызова функции. HM-система требует, чтобы все функции были объявлены, а не подразумевались, и каждое имя может иметь только один тип (тогда как методы Go могут иметь разные типы в разных интерфейсах).

Вместо этого Go требует, чтобы функции всегда были полностью объявлены, но позволяет переменным использовать вывод типа. Это возможно, потому что правая часть назначения variable := expressionуже имеет известный тип в этой точке программы. Этот тип вывода типа является простым, правильным и линейным.

  • Тип переменной сразу известен в точке объявления, тогда как вывод HM должен сначала проверить тип всей программы. Это также заметно влияет на качество сообщений об ошибках.
  • Подход с выводом типа в Go всегда будет выбирать наиболее конкретный тип для переменной, в отличие от HM, который выбирает наиболее общий тип. Это чисто работает с подтипами, даже с неявными интерфейсами Go.
Амон
источник
24
@bishop Это «рассуждение» для бесконечно малых значений «разума».
Хоббс
18
@bishop Выполнив работу компилятора на языках с генериками, я, конечно, могу согласиться: это трудно реализовать без существенного усложнения реализации. Я бы зашел так далеко, что даже заменил «трудное» на «невозможное». Однако дело не в этом; Дело в том, стоит ли дополнительных сложностей? И ответ для всех, кто работал с генериками и без них, очевидно, «да, определенно!» Я должен был бы полностью согласиться с утверждением, что отказ от реализации дженериков, потому что «о нет, сложность» идиотский.
Мейсон Уилер
18
Именно поэтому разработчики Go делают вид, что FP всех видов плох; Go имеет функцию первого класса с лексическим закрытием, и с тем , что способность создавать функции высшего порядка, но это невозможно , чтобы поместить их в какое - либо хорошем применение , так как типы таких основных функций , как map, filterи reduceвсе невыразимые в Гоу очень ограничено система типов.
Хоббс
9
@hobbs And Go мог бы быть действительно хорошим языком, если бы это было исправлено, но вместо этого люди должны писать библиотеки общего поколения, такие как gengenиgonerics
cat
14
@cat Это позор. Поначалу Go кажется отличным языком, полным замечательных идей, но затем вы понимаете, что у него нет наследования и полиморфизма, поэтому вы не можете хорошо выполнять ООП, и у него нет обобщений, поэтому вы не можете хорошо выполнять FP, и вы остаются пустыми, глядя на экран и спрашивая: «Тогда как именно вы должны использовать этот язык?!?»
Мейсон Уилер