Это тесно связано с вашим другим вопросом о Haskell и быстрой сортировке. Я думаю, что вам, вероятно, нужно прочитать хотя бы введение книги о Хаскелле. Звучит так, как будто вы еще не поняли ключевой момент, который заключается в том, что он запрещает вам изменять значения существующих переменных.
Своп (как он понимается и используется в C ++) по своей сути сводится к изменению существующих значений. Таким образом, мы можем использовать имя для ссылки на контейнер и заменить этот контейнер совершенно другим содержимым, а также специализировать эту операцию, чтобы она была быстрой (и свободной от исключений) для конкретных контейнеров, что позволяет нам реализовывать подход изменения и публикации (крайне важно для написания кода, исключающего исключение, или попытки написать код без блокировки).
Вы можете написать общий своп в Haskell, но он, вероятно, возьмет пару значений и вернет новую пару, содержащую те же значения с обратными позициями, или что-то в этом роде. Не совсем то же самое, и не имеет одинакового использования. Не было бы никакого смысла пытаться специализировать ее для карты, копаясь в этой карте и меняя ее отдельные переменные-члены, потому что вы просто не можете делать такие вещи в Haskell (вы можете выполнять специализацию, но не модификация переменных).
Предположим, мы хотели "измерить" список в Haskell:
measure :: [a] -> Integer
Это объявление типа. Это означает, что функция measure
принимает список чего угодно (a
является параметром универсального типа, поскольку он начинается со строчной буквы) и возвращает целое число. Так что это работает для списка любого типа элемента - это то, что называется шаблоном функции в C ++ или полиморфной функцией в Haskell (не то же самое, что полиморфный класс в C ++).
Теперь мы можем определить это, предоставив специализации для каждого интересного случая:
measure [] = 0
т.е. измерьте пустой список, и вы получите ноль.
Вот очень общее определение, которое охватывает все другие случаи:
measure (h:r) = 1 + measure r
Бит в скобках на LHS является шаблоном. Это значит: взять список, отрубить голову и назвать его h, назвать оставшуюся часть r. Эти имена являются параметрами, которые мы можем использовать. Это будет соответствовать любому списку с хотя бы одним элементом.
Если вы пробовали метапрограммирование шаблонов в C ++, это все будет для вас старомодно, поскольку в нем используется один и тот же стиль - рекурсия для выполнения циклов, специализация для завершения рекурсии. За исключением того, что в Haskell он работает во время выполнения (специализация функции для определенных значений или шаблонов значений).