The minimal code:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
return twice ++ "H"
The errors generated:
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"
| ^^^
How would I logically fix this issue myself? Clearly it's something I'm doing wrong. Am I missing a preamble that every example should have?
As RobinZigmond mentions in the comments, you can’t write twice ++ "H"
. This means, ‘take the function twice
, and append the string "H"
to it’. This is clearly impossible, since ++
can only append strings and lists together. I suspect that what you meant was twice (++ "H")
. This takes the function (++ "H")
, which appends "H"
to the end of its argument, and runs it twice.
But even if you do this, there is still a problem. Take a look at the program which is created if you do this:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
return (twice (++ "H"))
Even though this program compiles, it doesn’t do anything! You have set twice (++ "H"))
as the return value of main
, but the return value of main
is always ignored. In order to produce output, you need to use putStrLn
instead of return
:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
putStrLn (twice (++ "H"))
But this program doesn’t work either! twice (++ "H")
is a function, which cannot be printed. This function must be applied to a value in order to produce a result:
twice :: (a -> a) -> a -> a
twice f = f . f
main = do
putStrLn (twice (++ "H") "Starting value")
This program should finally work, giving an output of Starting valueHH
when it is run.