Я не думаю, что ваш первый пример - очень Haskell-y, поскольку вы перегружаете одно и то же имя, чтобы сделать две совершенно разные вещи. В Haskell, когда вы отображаете функцию на некоторый контейнер, вы ожидаете получить тот же тип контейнера. На самом деле, это так распространено в Haskell, что существует класс типов Functor
, который инкапсулирует этот шаблон.
Все формы перегрузки в Haskell сводятся к использованию классов типов, и хотя вы можете использовать их для достижения чего-то похожего, это было бы очень надуманным и не очень полезным по сравнению с использованием простых функций, выполняющих только одну вещь, которую вы хотите.
Prelude> import qualified Data.Map as M
Prelude Data.Map> let m = M.fromList [(2, 'a'), (6, 'b')]
Prelude Data.Map> M.map show $ M.mapKeys (+1) m
fromList [(3,"'a'"),(7,"'b'")]
Prelude Data.Map> M.keys m
[2,6]
Я думаю, что ваш второй пример больше относится к Haskell, так как он больше касается выбора наиболее эффективной реализации структуры данных на основе содержимого типа, и я подозреваю, что это не должно быть слишком сложно сделать с использованием типа семьи , но я не слишком знаком с ними, поэтому я позволю кому-то другому попытаться ответить на эту часть.