Haskell 为 'show' 显式声明参数时出现 IO-Monad 错误
Haskell IO-Monad error upon explicitly stating parameter for 'show'
虽然我觉得自己对 Haskel IO 和 Monads 有很好的理解,但我很难理解以下错误消息。
考虑 Haskell
中的以下简单函数
testf :: Show a => a -> String
testf x = show x
我尝试实现一个使用 IO Monad 打印到控制台的变体
printtoscreen :: Show a => a -> IO()
printtoscreen x = putStrLn . show x
但是,这会产生以下错误:
Couldn't match type ‘[Char]’ with ‘a0 -> String’
Expected type: a0 -> String
Actual type: String
正确的版本应该省略明确说明 x
参数
printtoscreen :: Show a => a -> IO()
printtoscreen = putStrLn . show
我明白为什么最后一个代码片段有效,但我无法理解第二个代码片段的错误消息,考虑到它也会 return 一个字符串到 putStrLn
那么为什么要在 IO()
变体中省略 x
参数?
.
,函数组合运算符,需要一个函数。 show x
然而不是函数;它是一个评估值([Char]
类型)在它被赋予 .
.
时
您必须改用函数应用程序运算符:
printtoscreen x = putStrLn $ show x
So why should the x
parameter be omitted in the IO ()
variant?
这与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
,因此错误。
虽然我觉得自己对 Haskel IO 和 Monads 有很好的理解,但我很难理解以下错误消息。
考虑 Haskell
中的以下简单函数testf :: Show a => a -> String
testf x = show x
我尝试实现一个使用 IO Monad 打印到控制台的变体
printtoscreen :: Show a => a -> IO()
printtoscreen x = putStrLn . show x
但是,这会产生以下错误:
Couldn't match type ‘[Char]’ with ‘a0 -> String’ Expected type: a0 -> String Actual type: String
正确的版本应该省略明确说明 x
参数
printtoscreen :: Show a => a -> IO()
printtoscreen = putStrLn . show
我明白为什么最后一个代码片段有效,但我无法理解第二个代码片段的错误消息,考虑到它也会 return 一个字符串到 putStrLn
那么为什么要在 IO()
变体中省略 x
参数?
.
,函数组合运算符,需要一个函数。 show x
然而不是函数;它是一个评估值([Char]
类型)在它被赋予 .
.
您必须改用函数应用程序运算符:
printtoscreen x = putStrLn $ show x
So why should the
x
parameter be omitted in theIO ()
variant?
这与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
,因此错误。