Подпись типа Haskell MonadWriter - PullRequest
4 голосов
/ 26 марта 2019

Вопрос Noob на MonadWriter:

monadWrite :: Writer String Int
monadWrite = writer (3003, "log 1\n") 

Почему String стоит первым в типизме, а Int - вторым, тогда как 3003 - это явно Int, а "log 1\n" - String. Тривиально я знаю, но хотелось бы понять.

1 Ответ

7 голосов
/ 26 марта 2019

Нет особой причины ставить результат (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

Вычерчивание порядка в Хаскеле

...