При переходе к Haskell с опытом работы на различных объектно-ориентированных языках, мне кажется, что один недостаток заключается в том, что имена функций и полей не привязаны к типам, с которыми они связаны, поэтому легко столкнуться с конфликтами, если разные типы данных имеют поля с одинаковыми именами.
Если у меня есть эти три модуля:
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
считаются неоднозначными, даже если только одно из двух импортированных имен имеет смысл в этом контексте. (На языке OO ссылки на foo.value
и bar.value
будут однозначными.)
Конечно, я могу устранить неоднозначность, написав Foo { One.value = 42 }
, но это выглядит неловко. Я также могу назвать поля по-разному, например "fooValue" и "barValue", но избыточность в Foo { fooValue = 42 }
тоже выглядит неудобной.
Это действительно частный случай более общей проблемы функций в разных модулях, которые имеют одно и то же имя, но работают с разными, не связанными типами. Хотя я, кажется, чаще сталкиваюсь с этим с именами полей. Например, у меня есть несколько типов данных, не связанных классом типа, но часто используемых вместе, которые содержат значения цвета, поэтому я бы хотел, чтобы у каждого из них было поле с именем «цвет».
Как опытные разработчики Haskell называют вещи и организовывают их в модули, чтобы избежать подобных ситуаций?
Bar
отсутствует конструктор. - person Travis Brown   schedule 19.07.2010