Столкновения имен между метками полей разных типов данных в Haskell - PullRequest
15 голосов
/ 19 июля 2010

Приходя к Haskell из фона на разных языках OO, мне кажется, что недостатком является то, что имена функций и полей не ограничиваются типами, с которыми они связаны, поэтому легко запускать в конфликты, если разные типы данных имеют поля с одинаковыми именами.

Если у меня есть эти три модуля:

module One where

data Foo a = Foo { value :: a }

----

module Two where

data Bar a = Bar { value :: a }

----

module Three where

import One
import Two

foo = Foo { value = 42 }  -- compile error here
n = value foo  -- and here

безусловные ссылки на value в модуле Three считаются неоднозначными, даже если в этом контексте имеет смысл только одно из двух импортированных имен. (На языке ОО ссылки на foo.value и bar.value были бы однозначными.)

Конечно, я могу устранить неоднозначность, написав Foo { One.value = 42 }, но это выглядит неловко. Я также могу назвать поля по-разному, например, "fooValue" и "barValue", но избыточность в Foo { fooValue = 42 } также выглядит неловко.

Это действительно частный случай более общего вопроса о функциях в разных модулях, которые имеют одинаковое имя, но работают с разными, не связанными типами. Я, кажется, сталкиваюсь с этим чаще с именами полей, хотя. Например, у меня есть несколько типов данных, не связанных классом типов, но часто используемых вместе, которые содержат значения цвета, поэтому я бы хотел, чтобы у каждого было поле с именем "color".

Как опытные разработчики на Haskell называют вещи и объединяют их в модули, чтобы избежать подобных ситуаций?

Ответы [ 3 ]

9 голосов
/ 19 июля 2010

Расширение GHC -XDisambiguateRecordFields позволит foo = Foo { value = 42 } (но не n = value foo).

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

Этот вопрос StackOverflow похож, и некоторые ответы там также могут быть полезны для вас..

Это действительно частный случай более общего вопроса о функциях в разных модулях, которые имеют одинаковые имена, но работают с разными, не связанными типами.

Квалифицированного импорта и псевдонимов обычно достаточно, чтобы решить эту проблему.

4 голосов
/ 19 июля 2010

Как опытные разработчики на Haskell называют вещи и объединяют их в модули, чтобы избежать подобных ситуаций?

Я работал только с несколькими опытными разработчиками на Haskell, и они делают ужасные вещи вроде

data Foo a = Foo { foo_value :: a }

data Bar a = Bar { bar_value :: a }

или даже

data Apocalypse a = A { ap_value :: a }

В общем, у меня такое ощущение, что многим старым хаскелерам не нравятся квалифицированные имена и они действительно хотят притворяться, что в мире есть только одно большое пространство имен, прямо из темных веков. (Было время, когда компиляторы C имели те же ограничения на имена полей, поэтому режим в struct stat называется st_mode, а не просто mode.)

Вы можете перегружать имена классами типов, но опытные разработчики, которых я знаю, не любят бесплатные классы типов. Я никогда не могу понять, когда они думают, что класс типов будет бесплатным или нет.

Я надеюсь, что однажды люди на Haskell придут к соглашению с иерархическим пространством имен и начнут использовать квалифицированные имена. Как и предполагал Бог.

1 голос
/ 19 июля 2010

Вы можете рассмотреть класс типов, если у всех этих типов есть общая функция доступа.Например,

class Fieldable a where
     field :: a -> b

instance Fieldable (a,b) where
     field = fst

и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...