0

以下は私の食事する哲学者のコードであり、「'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) ]
4

1 に答える 1

6

コードには多くの問題があります。

報告するエラーメッセージは、おそらくスペースとタブが混在していることを示しています。タブを取り除き、スペースのみを使用してください。


あなたはおそらく、Haskellプログラムの作成を練習するためにこのプログラムを作成しているのであって、楽しみと利益のためにプログラムを実行するためではありません。ですから、私たちは単にあなたに実用的な食事する哲学者の実装を与えるのではなく、あなたがあなたの実装を書くのを手伝いたいのです。

あなたのコードから、あなたがそれがどのように機能することを期待しているのかわかりません。

最後の行に焦点を当てます:

sequence_ [ forkIO forks (mVar philosopher) ]

sequence_ :: [IO a] -> IO ()--- sequence_i / oアクションのリストを提供し、各アクションを順番に実行します(i / oアクションを返します)。から、[...]リストを提供しようとしているように見えますが、要素は1つだけです。これはおそらくあなたが言っていることではありません。

forkIO :: IO () -> IO ThreadID--- forkIOI / Oアクションを指定すると、新しいスレッドで実行されているI / Oアクションが開始され(そのI / Oアクションが返されます)、そのスレッドのIDが提供されます。

ここには2つの問題があります。

  • forksは関数であり、i / oアクションではありません(おそらくそれを意味しているとはいえ、i / oアクションを返す関数でもありません)
  • あなたforkIOは2番目の引数((mVar philosopher))を与えますが、それは1つの引数しか取りません

mVar philosopherそれ自体は意味がありません:(mVar :: [MVar a]これはMVarのリストであり、MVarに含まれるべきタイプはわかりません)がphilosopher、引数として渡す関数のように扱います。

この時点で、私の頭の上で電球が点滅します。forksパラメータmVarphilosopher?を使用して呼び出します。

sequence_ [ forkIO (forks mVar philosopher) ]

ただし、まだ1つのアクションをシーケンス処理しています。forksおそらく、の各要素をphilosopher順番に呼び出したいですか?

sequence_ $ map (\n -> forkIO (forks mVar n)) philosopher

これを単純化して

mapM_ (\n -> forkIO (forks mVar n)) philosopher

これは、指定したタイプと一致しませんforks :: [MVar] -> [Int]。しかし、それはおそらく間違っているので、次にその関数を修正する必要があります。

于 2012-05-24T19:30:00.287 に答える