Различия между конструкторами данных / типов и функциями? - PullRequest
9 голосов
/ 18 марта 2011

Может ли кто-нибудь объяснить мне, в чем различия между конструкторами данных / типов и функциями?Haskell смешивает их и дает нам универсальный интерфейс (все выглядят как функции, в частности, мы можем частично применять их), тогда как языки семейства ML различают их.

Ответы [ 3 ]

18 голосов
/ 18 марта 2011

Ваша дихотомия "Haskell против мира ML" неверна¹.SML также продвигает конструкторы для функций, а Caml Light - для.Я не уверен, почему он был удален в OCaml, я думаю, дизайнер подумал, что в этом нет особой необходимости.

Существуют глубокие причины, по которым конструкторы немного специфичны.Они могут использоваться в шаблонах, в то время как общие функции не могут - я думаю, это можно объяснить в терминах поляризованной логики и фокусировки2.Кроме того, конструктор, примененный к значениям, может рассматриваться как значение, хотя это не так для общих функций.В языках вызовов по значению принято ограничивать определение рекурсивных значений подклассом, который допускает применение конструктора, но не приложение общей функции.

Я согласен, что «семантический сахар» продвижения всех конструкторов в функцииотлично.Однако я думаю, что это было бы не очень полезно, если бы у нас был хороший синтаксический сахар для короткой абстракции, такой как Some(_) от Scala.Должны ли конструкторы быть вычеркнутыми (ваше замечание о «частичном применении») или нет - это другой и ортогональный вопрос, на мой взгляд.

¹: помимо неправильной дихотомии, тон вашего вопроса имеет определенный вкус«Хаскелеры и MLers, вот кольцо, пожалуйста, борись!».Это не может быть преднамеренным, но в любом случае вам следует избегать таких формулировок.Языковой дизайн сделан из компромиссов, и допущение, когда два разных языка сделали разные выборы, что один из них правильный , а не другой, не является хорошим подходом.

PS:с тех пор вопрос был отредактирован и теперь стал гораздо более нейтральным.Спасибо за редактирование.

²: по просьбе petebu, здесь есть немного больше (на самом деле намного больше) информации о «фокусировке и полярности».Я хотел бы отметить, что я действительно не эксперт по этой теме (отсюда и «я думаю»).

Я бы рекомендовал сначала статью Сосредоточение на сопоставлении с образцом (PDF) от Neelakantan Krishnaswami, 2009. Он содержит введение для людей, не разбирающихся в поляризованной логике и фокусировке (но вы должны быть хотя бы знакомы с последовательным исчислением).Как обычно в последовательном исчислении, типы / предложения вводятся «справа» и исключаются / деконструируются «слева».Но здесь мы разделяем типы по «полярности», продукт и суммы являются положительными, а функции - отрицательными (моя интуиция заключается в том, что продукт / суммы - это данные, а функции - вычисления, но разделение мотивируется очень естественными соображениями относительно их поведения в последовательном исчислении),и в статье показано, что исключение слева типов стрелок соответствует применению функции, а исключение слева типов суммы / произведения соответствует сопоставлению с образцом.Существует конструкция case, которая ведет себя аналогично сопоставлению с образцом (с некоторыми отличиями), которая исключает положительные значения, поэтому ее нельзя применять к функциям.

Другой важной ссылкой будет Сосредоточение на связывании иВычисления Дана Ликаты, Ноама Цейлбергера и Роберта Харпера, 2008 г. (обратите внимание, что если вы планируете представить доклад по этим темам, «Сосредоточиться на ...» становится немного клише).В нем гораздо меньше подчеркивается связь с сопоставлением с образцом в стиле ML, но вводится очень приятная идея, что, хотя вычислительные стрелки «отрицательны слева» (легко воспринимаемые как классическая эквивалентность A→B ≡ ¬A∨B), можно ввести другую стрелку ».положительный слева ", поэтому положительно поляризованный, который может быть сопоставлен с шаблоном.Оказывается, эта стрелка хорошо подходит для представления привязок переменных (если вы знакомы с абстрактным синтаксисом высшего порядка, идея состоит в том, что левая полярность исключает «экзотические термины», которые пытаются вычислить их переменные), так чтоТермины с привязками переменных - это структура данных, которая может быть сопоставлена ​​с шаблоном, как суммы или продукты.
I fouи их бумаги немного трудно читать, поэтому я бы начал с слайдов Дана Ликаты .Наконец, Роберт Харпер сделал другие слайды , которые дают иную интуицию в терминах индуктивных суждений / дериваций: положительные стрелки представляют выводимость (не могли бы вы построить деривацию C по гипотезе Aи B?) в то время как отрицательные стрелки представляют допустимость (учитывая производные A и B, как бы вы переписали / исследовали / манипулировали ими для создания производного C?).Очень интересные вещи.

1 голос
/ 19 марта 2011

Сначала необходимо объяснить разницу между значением и типом.

"Поскольку Haskell является чисто функциональным языком, все вычисления выполняются посредством оценки выражений (синтаксических терминов) для получения значений (абстрактных объектов, которые мы рассматриваем как ответы). Каждое значение имеет связанный тип."- Деликатное введение в Haskell 98 (этот урок не совсем мягкий)

Значения Haskell являются «первоклассными», а типы Haskell - нет.Типы используются для описания значений, а связь значения и его типа называется типизацией.

Разница между конструктором данных / типа заключается в следующем: применение конструктора данных дает значение, а применение конструктора типа - тип.

Функции - это просто выражения, описывающие значения, которые связаны стип.Когда вы оцениваете функцию, вы просто оцениваете выражения, описывающие значения.

0 голосов
/ 18 марта 2011

Haskell действительно уменьшает и упрощает некоторые синтаксисы OCaml.Но синтаксис Haskell однозначно различает конструкторы и функции.Функции начинаются со строчной буквы, а конструкторы начинаются с заглавной буквы.С инфиксными операторами конструкторы данных должны начинаться с двоеточия, а нормальные операторы никогда не могут начинаться с двоеточия.

Интерфейс для конструкторов может выглядеть как простое (возможно, частичное) применение функции, это делает конструкторы с одним аргументом и большинство новых типов оченьпрост в использовании (просто "привет").Но Haskell позволяет вам использовать OCaml-подобные имена записей и стиль {field = value, field = value}, хотя в Haskell вы не обязаны иметь имена полей или использовать этот синтаксис.Таким образом, OCaml имеет простой синтаксис только для отдельных полей, но Haskell позволяет использовать простой синтаксис для нескольких полей.В конце концов, избегать имен полей плохо для большого типа, так как позиционный функционально-подобный синтаксис труднее реорганизовать.

...