Почему конструкторы данных с одинаковыми именами запрещены в конструкторах разных типов?

11

Следующая декларация выдает ошибку:

type Vec2d = (Float, Float)
type Vec3d = (Float, Float, Float)
-- Rect x y defines a rectangle spanning from (0,0) to (x,y)
data Obj2d = Rect Float Float
           | Translate Vec2d Obj2d
-- Cuboid x y z defines a cuboid spanning from (0,0,0) to (x,y,z)
data Obj3d = Cuboid Float Float Float
           | Translate Vec3d Obj3d

а именно Multiple declarations of 'Translate'.

Теперь мне интересно, почему это ограничение было введено?

Если бы ограничения не было, можно было бы написать

Translate (1, 1) Rect 2 2 и Translate (1, 2, 3) Cuboid 1 1 1, что звучит естественно.

Я (сразу) не вижу, как это может привести к проблеме синтаксического анализа, запрещающей использование одного и того же имени, тип может быть выведен по аргументу ( Rect 2 2is Obj2d, Cuboid 1 1 1is a Obj3d).

Я уверен, что есть веская причина, по которой разработчики языка решили запретить использование одного и того же имени для конструкторов данных разных типов, но я хотел бы узнать: почему, когда это явно не нужно?

(И устранение неоднозначности типа - дело Хаскелла, связанное с хлебом и маслом!)

СЗ
источник
3
Относительно типа, определяемого аргументом: знаете ли вы, что иногда тип аргумента выводится из типа функции ?
@delnan Я не знал об этом ... звучит как ответ для меня. Я всегда полагал, что логический вывод был снизу вверх, хотя я мог видеть разрешение неоднозначности, используя информацию о типах с другой стороны графа типов, который вы описываете как решающий фактор ... мой мысленный образ для этого - возвращаемые типы в нижней части вызовы графиков и функций вверху, разрешение - это совокупность, образованная складыванием снизу, но это не совсем вся картина, вы говорите? Неудивительно, что в языке с зависимой типизацией и совершенным выводом это, вероятно, более точно ..
Джимми Хоффа

Ответы:

13

Это потому, что конструкторы данных - это просто функции, а перегрузка функций в Haskell недопустима. Это может быть более понятно, если вы используете синтаксис GADT для определения ваших типов:

{-# LANGUAGE GADTs #-}
data Obj2d where
    Rect :: Float -> Float -> Obj2d   -- a function from floats to obj2d's
    Translate :: Vec2d -> Obj2d       -- a function from vec2d's to Obj2d's

Я полагаю, что они (разработчики GHC) работают над возможными решениями этой проблемы, включая введение нового type classдля всех типов, которые используют один и тот же конструктор данных, или что-то подобное. Так что следите за обновлениями, решение вашей проблемы может появиться в ближайшее время! (Я надеюсь)

bstamour
источник
Я определенно с нетерпением жду этих type classконструкций, которые вы предусмотрели. - Причина в том , у меня нет проблем, я могу сделать Translate2и Translate3d, но я предпочел бы не загрязнять пространство имен.
Сз
Я не разработчик GHC, так что просто слушай, говори. Я надеюсь, что это тоже случится.
bstamour