最小代码:
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"
| ^^^
我如何逻辑上自己解决此问题?显然这是我做错的事情。我是否错过了每个示例都应有的序言?
答案 0 :(得分:3)
正如罗宾·齐格蒙德(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
的返回值,但始终会忽略main
的返回值。为了产生输出,您需要使用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
。