предлагается ввести type class Cipher, который "captures the general behavior of encoding and decoding messages".
class Cipher a where
encode :: a -> String -> String
decode :: a -> String -> String
data Rot = Rot
instance Cipher Rot where
encode Rot text = rotEncoder text
decode Rot text = rotDecoder text
И пример использования: encode Rot "Haskell".
Тут возникает два вопроса:
1. Раньше в книге в качестве аргументов передавались значения или функции. А тут (по-моему, в первый раз в книге) передается type constructor. (Убедился, что это именно он, путем переименования). Может быть, type constructor это функция? Но тогда Rot – это функция с нулевой арностью? Непонятно, почему про это ничего не сказано в книге, или я плохо читаю?
Если так, то и константы могут быть аналогичными функциями.
2. Сам пример выглядит как-то искусственно. Какой смысл в выделении general behavior, если пользователю функции все равно надо вручную указать некий "Rot". С тем же успехом можно знать, что надо вызвать rotEncoder.
Конечно, одна функция и аргумент, управляющий выбором конкретной реализации, это более гибкий подход, чем разные названия функций, но все равно "правильным", на мой взгляд, было бы автоматическое определение варианта реализации. Вот как у minBound, maxBound, например. Почему тут не сделано так?
--
Отдельный вопрос вызывает предлагаемая реализация xor, тоже могу запостить, если интересно
тут передается data конструктор
Обсуждают сегодня