Вопрос новичка о MonadWriter:
monadWrite :: Writer String Int
monadWrite = writer (3003, "log 1\n")
Почему String
идет первым в typeig и Int
вторым, тогда как 3003
явно Int
, а "log 1\n"
- String
. Я знаю банально, но хочу понять.
Вопрос новичка о MonadWriter:
monadWrite :: Writer String Int
monadWrite = writer (3003, "log 1\n")
Почему String
идет первым в typeig и Int
вторым, тогда как 3003
явно Int
, а "log 1\n"
- String
. Я знаю банально, но хочу понять.
Нет особой причины помещать результат (3003
) первым, а результат ("log 1\n"
) второй в аргументе для writer
. Я полагаю, что порядок был выбран в соответствии с внутреннее представление WriterT
:
newtype WriterT w m a = WriterT { runWriterT :: m (a, w) }
(для Writer
, m
- это личность).
Однако в сигнатуре типа для Writer
порядок аргументов имеет значение. Если мы посмотрим, например, на класс типов Functor
с членом
fmap :: (a -> b) -> f a -> f b
это позволяет заменить Writer String
(или, как правило, Writer result
) на f
и получить
fmap :: (a -> b) -> Writer result a -> Writer result b
что в точности соответствует правильному порядку аргументов. Их замена сделает реализацию Functor
невозможной (без некоторых уловок).
Это верно для всех типов / функций, которые принимают более одного параметра: единственный способ их использования в качестве типов / функций с одним аргументом - это изменение последнего аргумента, а не других.
См. Связанные вопросы, в которых обсуждаются похожие проблемы:
Изменить порядок аргументов для объявления экземпляра в Haskell
Неупорядоченное каррирование в Haskell