Haskell Ошибка ввода-вывода при явном указании параметра 'show' - PullRequest
1 голос
/ 08 января 2020

Хотя мне кажется, что я хорошо понимаю Haskel IO и Monads, мне трудно понять следующее сообщение об ошибке.

Рассмотрим следующую простую функцию в Haskell

testf :: Show a => a -> String
testf x = show x

Я попытался реализовать вариант, который печатает на консоль с помощью моно ввода-вывода

printtoscreen :: Show a => a -> IO()
printtoscreen x = putStrLn . show x

Однако это приводит к следующей ошибке:

Не удалось сопоставить тип '[Char]' с 'a0 -> String' Ожидаемый тип: a0 -> String Фактический тип: String

В правильной версии следует явно указать параметр x

printtoscreen :: Show a => a -> IO()
printtoscreen = putStrLn . show
.

Я понимаю, почему работает последний фрагмент кода, но я не могу понять смысл сообщения об ошибке второго фрагмента кода, учитывая, что он также вернет строку в putStrLn

Так почему Параметр x опустить в варианте IO()?

Ответы [ 2 ]

5 голосов
/ 08 января 2020

., оператор композиции функции, ожидает функцию. show x однако не является функцией; это оценочное значение (типа [Char]) к моменту, когда оно передано ..

Вместо этого вам придется использовать оператор приложения функции:

printtoscreen x = putStrLn $ show x
3 голосов
/ 08 января 2020

Так почему параметр x должен быть опущен в варианте IO ()?

Это не имеет ничего общего с самим IO (). Вы здесь используете функцию композиции. Действительно, функция (.) :: (b -> c) -> (a -> b) -> a -> c определяется как:

(.) :: (b -> c) -> (a -> b) -> a -> c
(.) f g x = f (g x)

Таким образом, она используется для объединения двух функций f и g в новом функция, которая сначала применяет g к параметру, а затем f к результату g x.

Если вы напишите:

printtoscreen x = putStrLn . show x

, тогда функция (.) будет разрешите это следующим образом:

printtoscreen x = \y -> putStrLn (show x y)

или, следовательно, проще для чтения:

printtoscreen x y = putStrLn (show x y)

Это будет означать, что show должен иметь тип Show a => a -> b -> String, но имеет тип show :: Show a => a -> String, следовательно, ошибка.

...