gtk2hs:无法将预期类型“IO [Int]”与实际类型“[Int]”相匹配

gtk2hs: Couldn't match expected type ‘IO [Int]’ with actual type ‘[Int]’

大家 我想从 GUI 中获取数字列表,以使用 gtk2hs 进行一些更改,并将结果 return 发送到 GUI。但是,它有很多错误。我是 Haskell 的菜鸟,谁能告诉我如何解决它。谢谢!!

import Graphics.UI.Gtk
import Data.List 

main :: IO ()
main= do
  initGUI
  window <- windowNew
  set window [windowTitle := "Text Entry", containerBorderWidth := 10]

  vb <- vBoxNew False 0
  containerAdd window vb

  hb <- hBoxNew False 0
  boxPackStart vb hb PackNatural 0

  txtfield <- entryNew
  boxPackStart hb txtfield PackNatural 5
  button <- buttonNewFromStock stockInfo
  boxPackStart hb button PackNatural 0

  txtstack <- statusbarNew
  boxPackStart vb txtstack PackNatural 0
  id <- statusbarGetContextId txtstack "Line"

  widgetShowAll window
  widgetSetSensitivity button False

  onEntryActivate txtfield (saveText txtfield button txtstack id)
  onPressed button (statusbarPop txtstack id)
  onDestroy window mainQuit
  mainGUI

  saveText :: Entry -> Button -> Statusbar -> ContextId -> IO ()
  saveText fld b stk id = do
                        txt <- entryGetText fld
                        result <- convert txt
                        lt <- first resultt
                        result2 <- combineTogether lt
                        mesg <-  " is the first element of input text" ++ txt

                        widgetSetSensitivity b True
                        msgid <- statusbarPush stk id mesg
                        return ()
convert :: [Int] -> IO [Int]
convert lstr = map read $ words lstr :: [Int]

converttoStr lst = map show lst 

combineTogether :: [Int] -> IO[Char]
combineTogether lst = intercalate " " (converttoStr lst)

first :: [Int] -> IO [Int]
first (x:xs) = xs

错误信息如下:

[1 of 1] Compiling Main             ( testproject.hs, testproject.o )

testproject.hs:39:38:
Couldn't match type ‘[]’ with ‘IO’
Expected type: IO Char
  Actual type: [Char]
In a stmt of a 'do' block:
  mesg <- " is the first element of input text" ++ txt
In the expression:
  do { txt <- entryGetText fld;
       result <- convert txt;
       lt <- first result;
       result2 <- combineTogether lt;
       .... }
In an equation for ‘saveText’:
    saveText fld b stk id
      = do { txt <- entryGetText fld;
             result <- convert txt;
             lt <- first result;
             .... }

testproject.hs:39:79:
Couldn't match type ‘Int’ with ‘Char’
Expected type: [Char]
  Actual type: [Int]
In the second argument of ‘(++)’, namely ‘txt’
In a stmt of a 'do' block:
  mesg <- " is the first element of input text" ++ txt

testproject.hs:48:16:
Couldn't match expected type ‘IO [Int]’ with actual type ‘[Int]’
In the expression: map read $ words lstr :: [Int]
In an equation for ‘convert’:
    convert lstr = map read $ words lstr :: [Int]

testproject.hs:48:33:
Couldn't match type ‘Int’ with ‘Char’
Expected type: String
  Actual type: [Int]
In the first argument of ‘words’, namely ‘lstr’
In the second argument of ‘($)’, namely ‘words lstr’

testproject.hs:51:23:
Couldn't match expected type ‘IO [Char]’ with actual type ‘[Char]’
In the expression: intercalate " " (converttoStr lst)
In an equation for ‘combineTogether’:
    combineTogether lst = intercalate " " (converttoStr lst)

testproject.hs:54:16:
Couldn't match expected type ‘IO [Int]’ with actual type ‘[Int]’
In the expression: xs
In an equation for ‘first’: first (x : xs) = xs

Do-notation 是一系列绑定操作的语法糖。考虑到这一点,do 块中的每一行都必须是 'IO' 类型是有道理的,因为这就是您定义函数的方式。

尝试更改以下行

mesg <- " is the first element of input text" ++ txt

let mesg = " is the first element of input text" ++ txt

(也等同于)

mesg <- return " is the first element of input text" ++ txt

这应该可以解决您在该特定线路上遇到的问题。如果我们查看 'return' 函数的类型签名,它就更有意义了:

Monad m => a -> m a

这表示,"supply an 'a', and I will give you an 'a' wrapped inside a monad"(在本例中为 IO monad)

希望对您有所帮助。