import Control.Concurrent

main :: IO ()
main = do {
  sticks <- newSticks 5;
  startPhils sticks 1;
  phil 0 (last sticks) (head sticks);}

newSticks :: Int -> IO [MVar ()]
newSticks 0 = return []
newSticks n = do {
  stick <- newMVar ();
  sticks <- newSticks (n-1);
  return (stick:sticks);}

startPhils :: [MVar ()] -> Int -> IO ()
startPhils [_] _ = return ()
startPhils (sl:sr:sticks) n = do {
  forkIO (phil n sl sr);
  startPhils (sr:sticks) (n+1);}

phil :: Int -> MVar () -> MVar () -> IO ()
phil n l r = do {
  takeMVar l;
  takeMVar r;
  putStrLn (show n++" is eating");
  putMVar l ();
  putMVar r ();
  phil n l r;}