0

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?

4

1 回答 1

4

正如 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运行时间的输出。

于 2019-11-19T22:24:21.407 回答