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

时间:2012-05-24 18:22:28

标签: 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) ]

1 个答案:

答案 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作为参数传递。

此时,灯泡在我头顶闪烁。您希望使用参数forksmVar

致电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]类型不符。但这可能是错的,所以你接下来要修复那个功能。