我在Haskell中并发新手并且我试图获得一个结果,其中在main
线程中创建了一个新的MVar,将其空转到userThread
thread,从用户获取字符输入,然后将该值放入MVar并打开main
线程。
这是我到目前为止所拥有的
module Main where
import Control.Concurrent
import Control.Monad
import System.IO
import System.Random
import Text.Printf
data Msg = C Char | Time
main :: IO ()
main = do
hSetBuffering stdout NoBuffering
hSetBuffering stdin NoBuffering
hSetEcho stdin False
-- shared resources
chan <- newEmptyMVar
forkIO $ userThread chan
--r <- takeMVar chan
--show(r)
userThread :: MVar Msg -> IO ()
userThread chan = forever $ do
x <- getChar
putMVar chan (C x)
现在,我一直试图将输入的字符放入MVar,我已经粘贴了下面的错误
assignment1.hs:20:3: error:
* Couldn't match type `ThreadId' with `()'
Expected type: IO ()
Actual type: IO ThreadId
* In a stmt of a 'do' block: forkIO $ userThread chan
In the expression:
do { hSetBuffering stdout NoBuffering;
hSetBuffering stdin NoBuffering;
hSetEcho stdin False;
chan <- newEmptyMVar;
.... }
In an equation for `main':
main
= do { hSetBuffering stdout NoBuffering;
hSetBuffering stdin NoBuffering;
hSetEcho stdin False;
.... }
Failed, modules loaded: none.
任何正确方向的指针都将是一个很大的帮助! 谢谢大家
答案 0 :(得分:2)
forkIO $ userThread chan
是一个IO操作,返回ThreadId
,并且是main
do
块中的最后一个语句,它使main
返回。但是,您声明了main :: IO ()
,因此存在类型不匹配。
简单地返回一个虚拟元组。
main = do
...
forkIO $ userThread chan
return ()
(还有一个void
库函数,但你可以忽略它。)
答案 1 :(得分:2)
由于你在学习haskell时会一遍又一遍地得到这个错误,我想为你解压缩它:
assignment1.hs:20:3: error:
GHC为您提供文件,行号和列号:file:line:col
* Couldn't match type `ThreadId' with `()'
Expected type: IO ()
Actual type: IO ThreadId
Expected type
是指GHC期望表达式的类型,基于上下文,例如您提供的类型签名,或者您使用从该表达式返回的值的方式。 Actual type
是表达式的实际类型,例如文字'c'
的类型为Char
,map fst [('c', undefined)]
的实际类型为[Char]
等。
* In a stmt of a 'do' block: forkIO $ userThread chan
这是问题陈述。 forkIO
会返回ThreadId
(您可以从其类型签名中看到)。我想,这里的棘手部分是知道为什么类型检查器期望类型IO ()
(因为你的类型签名,以及在do
块的最后一个语句中返回的值这一事实将是返回的类型,如chi提到的。
让ghci
打开以帮助您在开发过程中回答这些问题时非常有用:
Prelude> import Control.Concurrent
Prelude Control.Concurrent> :t forkIO
forkIO :: IO () -> IO ThreadId
Prelude Control.Concurrent> :t ()
() :: ()
Prelude Control.Concurrent> :t repeat ()
repeat () :: [()]
如果你面前有这个文件,那么你可能不需要更多的上下文:
In the expression:
do { hSetBuffering stdout NoBuffering;
hSetBuffering stdin NoBuffering;
hSetEcho stdin False;
chan <- newEmptyMVar;
.... }
In an equation for `main':
main
= do { hSetBuffering stdout NoBuffering;
hSetBuffering stdin NoBuffering;
hSetEcho stdin False;
.... }
Failed, modules loaded: none.