编译错误:"'do'结构中的最后一个语句必须是表达式"

0 haskell dining-philosopher

以下是我的餐饮哲学家代码,并产生一个编译错误说"'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) ]
Run Code Online (Sandbox Code Playgroud)

dav*_*420 6

您的代码存在许多问题.

您报告的错误消息表明您可能正在混合空格和制表符.删除选项卡并仅使用空格.


你可能正在编写这个程序,以便练习编写Haskell程序,而不是为了运行程序以获得乐趣和利润.所以,我们不想简单地给你一个工作用餐哲学家实施,我们希望能帮助你写你的实现.

我无法从您的代码中看出您希望它如何工作.

我将专注于最后一行:

sequence_ [ forkIO forks (mVar philosopher) ]
Run Code Online (Sandbox Code Playgroud)

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第二个argunment((mVar philosopher)),但它只需要一个参数

mVar philosopher本身没有任何意义:( mVar :: [MVar a]这是一个MV的列表,我还没有弄清楚MVars应该包含什么类型)但是你把它当成一个函数,将它philosopher作为一个参数传递.

此时,灯泡在我头顶闪烁.你想forks用参数mVarphilosopher

sequence_ [ forkIO (forks mVar philosopher) ]
Run Code Online (Sandbox Code Playgroud)

我们仍在对一个动作进行排序.也许你想依次打电话forks给每一个元素philosopher

sequence_ $ map (\n -> forkIO (forks mVar n)) philosopher
Run Code Online (Sandbox Code Playgroud)

我们可以简化这个

mapM_ (\n -> forkIO (forks mVar n)) philosopher
Run Code Online (Sandbox Code Playgroud)

这与您给出的类型不符forks :: [MVar] -> [Int].但这可能是错的,所以你接下来要修复那个功能.