以下是我的餐饮哲学家代码并产生一个编译错误,说“'do'结构中的最后一个语句必须是一个表达式:mVar2< - newEmptyMVar mVar3” 有人可以帮我解决这个错误并让这个程序工作吗?谢谢
import Control.Concurrent
import Control.Concurrent.MVar
import System.Random
takefork :: Int -> forks -> IO ()
takefork n forks = takeMVar (forks!!n)
releasefork :: Int -> forks -> IO ()
releasefork n forks = putMVar (forks!!n)
philosopher :: [Int]
philosopher = [1,2,3,4,5]
forks :: [MVar] -> [Int]
forks = do
takefork n ( philosopher - 1)
threadDelay delay
let delay = 100000
takefork n philosopher
putStrLn("Philosopher" ++ philosopher ++ "has started eating")
releasefork n philosopher
releasefork n ( philosopher - 1)
ptStrLn ("Philosopher" ++ philosopher ++ "has stopped eating")
forks
main :: IO ()
main = do
mVar1 <- newEmptyMVar
mVar2 <- newEmptyMVar
mVar3 <- newEmptyMVar
mVar4 <- newEmptyMVar
mVar5 <- newEmptyMVar
let mVar = [mVar1, mVar2, mVar3, mVar4, mVar5]
sequence_ [ forkIO forks (mVar philosopher) ]
答案 0 :(得分:6)
您的代码存在许多问题。
您报告的错误消息表明您可能正在混合空格和制表符。摆脱标签并仅使用空格。
你可能正在编写这个程序,以便练习编写Haskell程序,而不是为了运行程序以获得乐趣和利润。所以我们不想简单地为您提供一个有效的Dining Philosophers实现,我们希望帮助您编写您的实现。
我无法从您的代码中看出您希望它如何运作。
我将专注于最后一行:
sequence_ [ forkIO forks (mVar philosopher) ]
sequence_ :: [IO a] -> IO ()
---给sequence_
一个I / O动作列表,然后它(返回一个i / o动作)按顺序执行每个动作。从[...]
开始,看起来你试图给它一个列表,但只有一个元素。这可能不是你的意思。
forkIO :: IO () -> IO ThreadID
---给forkIO
一个i / o动作,然后它(返回一个i / o动作)启动在新线程中运行的i / o动作,给你一个id那个帖子。
这里有两个问题:
forks
是一个函数,而不是一个i / o动作(它甚至不是一个返回i / o动作的函数,尽管你可能意味着它)。forkIO
第二个辩护((mVar philosopher)
),但只需要一个参数 mVar philosopher
本身没有任何意义:mVar :: [MVar a]
(这是MV的列表,我还没有弄清楚MVar应该包含哪种类型)但是你把它看作是一个函数,将philosopher
作为参数传递。
此时,灯泡在我头顶闪烁。您希望使用参数forks
和mVar
?
philosopher
sequence_ [ forkIO (forks mVar philosopher) ]
我们仍在对一个动作进行排序。也许您希望依次为forks
的每个元素调用philosopher
sequence_ $ map (\n -> forkIO (forks mVar n)) philosopher
我们可以将其简化为
mapM_ (\n -> forkIO (forks mVar n)) philosopher
这与您提供的forks :: [MVar] -> [Int]
类型不符。但这可能是错的,所以你接下来要修复那个功能。