Haskell :дублированные функции (+ )и (++ ), mappend

(+)и (++)являются просто специализациями mappend; я прав? Зачем они нужны? Это бесполезное дублирование, поскольку в Haskell есть мощные классы типов и вывод типов. Допустим, мы удаляем (+)и (++)и переименовываемmappend(+)для визуального удобства и набора текста. Кодирование было бы более интуитивным,короче и понятнее для новичков:

--old and new
1 + 2
--result
3

--old
"Hello" ++ " " ++ "World"
--new
"Hello" + " " + "World"
--result
"Hello World"

--old
Just [1, 2, 3] `mappend` Just [4..6]
--new
Just [1, 2, 3] + Just [4..6]
--result
Just [1, 2, 3, 4, 5, 6]

(Это заставляет меня мечтать. ). Три, а то и больше функций для одного и того же — это не очень хорошо для красивого языка, который настаивает на абстракции и таких вещах, как Haskell. Такие же повторы я видел и с монадами:fmapтакое же или почти такое же, как map, (.), liftM, mapM, forM,... Я знаю, что для fmapесть исторические причины, но как насчет моноидов? Планирует ли комитет Haskell что-то по этому поводу? Это сломает некоторые коды, но я слышал, хотя и не уверен, что скоро выйдет версия, в которой будут большие изменения, и это отличный повод. Очень жаль... По крайней мере, вилка доступна?

РЕДАКТИРОВАТЬ В ответах, которые я читал, есть тот факт, что для чисел в mappendможет вписаться либо (*), либо (+). На самом деле, я думаю, что (*)должен быть частью Monoid! Смотри:

В настоящее время, забыв о функциях memptyи mconcat, у нас есть только mappend.

class Monoid m where
    mappend :: m -> m -> m

Но мы могли бы сделать это:

class Monoid m where
    mappend :: m -> m -> m
    mmultiply :: m -> m -> m

Это было бы (может быть, я еще не достаточно об этом )вел бы себя следующим образом:

3 * 3
mempty + 3 + 3 + 3
0 + 3 + 3 + 3
9

Just 3 * Just 4
Just (3 * 4)
Just (3 + 3 + 3 +3)
Just 12

[1, 2, 3] * [10, 20, 30]
[1 * 10, 2 * 10, 3 * 10,...]
[10, 20, 30, 20, 40, 60,...]

На самом деле 'mmultiply' будет просто определен только в терминах 'mappend', поэтому для экземпляров Monoidнет необходимости переопределять его! Тогда Monoidближе к математике; возможно, мы могли бы также добавить в класс (-)и (/)! Если это сработает, я думаю, это решит случай Sumи Product, а также дублирование функций :mappend. становится (+), а новый mmultiplyпросто (*). В основном предлагаю рефакторинг кода с "подтягиванием". О, нам также понадобится новый memptyдля (*). Мы могли бы абстрагировать эти операторы в классе MonoidOperatorи определить Monoidследующим образом:

class (Monoid m) => MonoidOperator mo m where
    mempty :: m
    mappend :: m -> m -> m

instance MonoidOperator (+) m where
    mempty = 0
    mappend = --definition of (+)

instance MonoidOperator (*) where
    --...

class Monoid m where
    -...

Ну, я еще не знаю, как это сделать, но я думаю, что есть классное решение для всего этого.

11
задан L01man 9 June 2012 в 15:28
поделиться