Haskell 中的基本 "apply twice" hello world 类型不匹配
Type mismatch on basic "apply twice" hello world in Haskell
最小代码:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
return twice ++ "H"
产生的错误:
stack runhaskell "c:\Users\FruitfulApproach\Desktop\Haskell\test.hs"
C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:5:1: error:
* Couldn't match expected type `IO t0'
with actual type `[(a0 -> a0) -> a0 -> a0]'
* In the expression: main
When checking the type of the IO action `main'
|
5 | main = do
| ^
C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:6:20: error:
* Couldn't match type `Char' with `(a -> a) -> a -> a'
Expected type: [(a -> a) -> a -> a]
Actual type: [Char]
* In the second argument of `(++)', namely `"H"'
In a stmt of a 'do' block: return twice ++ "H"
In the expression: do return twice ++ "H"
* Relevant bindings include
main :: [(a -> a) -> a -> a]
(bound at C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:5:1)
|
6 | return twice ++ "H"
| ^^^
我自己如何从逻辑上解决这个问题?显然这是我做错的事情。我是否遗漏了每个示例都应该包含的序言?
正如 RobinZigmond 在评论中提到的,你不能写 twice ++ "H"
。这意味着,“获取函数 twice
,并将字符串 "H"
附加到它”。这显然是不可能的,因为 ++
只能将字符串和列表附加在一起。我怀疑你的意思是twice (++ "H")
。这采用函数 (++ "H")
,它将 "H"
附加到其参数的末尾,并且 运行 将其添加两次。
但是即使你这样做了,还是有问题。看看如果你这样做创建的程序:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
return (twice (++ "H"))
即使这个程序编译通过了,它也没有做任何事情!您已将 twice (++ "H"))
设置为 main
的 return 值,但始终忽略 main
的 return 值。为了产生输出,您需要使用 putStrLn
而不是 return
:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
putStrLn (twice (++ "H"))
但是这个程序也不行! twice (++ "H")
是函数,无法打印。此函数必须应用于一个值才能产生结果:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
putStrLn (twice (++ "H") "Starting value")
这个程序最终应该可以运行,在 运行 时给出 Starting valueHH
的输出。
最小代码:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
return twice ++ "H"
产生的错误:
stack runhaskell "c:\Users\FruitfulApproach\Desktop\Haskell\test.hs"
C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:5:1: error:
* Couldn't match expected type `IO t0'
with actual type `[(a0 -> a0) -> a0 -> a0]'
* In the expression: main
When checking the type of the IO action `main'
|
5 | main = do
| ^
C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:6:20: error:
* Couldn't match type `Char' with `(a -> a) -> a -> a'
Expected type: [(a -> a) -> a -> a]
Actual type: [Char]
* In the second argument of `(++)', namely `"H"'
In a stmt of a 'do' block: return twice ++ "H"
In the expression: do return twice ++ "H"
* Relevant bindings include
main :: [(a -> a) -> a -> a]
(bound at C:\Users\FruitfulApproach\Desktop\Haskell\test.hs:5:1)
|
6 | return twice ++ "H"
| ^^^
我自己如何从逻辑上解决这个问题?显然这是我做错的事情。我是否遗漏了每个示例都应该包含的序言?
正如 RobinZigmond 在评论中提到的,你不能写 twice ++ "H"
。这意味着,“获取函数 twice
,并将字符串 "H"
附加到它”。这显然是不可能的,因为 ++
只能将字符串和列表附加在一起。我怀疑你的意思是twice (++ "H")
。这采用函数 (++ "H")
,它将 "H"
附加到其参数的末尾,并且 运行 将其添加两次。
但是即使你这样做了,还是有问题。看看如果你这样做创建的程序:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
return (twice (++ "H"))
即使这个程序编译通过了,它也没有做任何事情!您已将 twice (++ "H"))
设置为 main
的 return 值,但始终忽略 main
的 return 值。为了产生输出,您需要使用 putStrLn
而不是 return
:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
putStrLn (twice (++ "H"))
但是这个程序也不行! twice (++ "H")
是函数,无法打印。此函数必须应用于一个值才能产生结果:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
putStrLn (twice (++ "H") "Starting value")
这个程序最终应该可以运行,在 运行 时给出 Starting valueHH
的输出。