Приходя к 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 называют вещи и объединяют их в модули, чтобы избежать подобных ситуаций?