止められる fib

これまた適当に書きました。sfib が汚い。フィボナッチ数を裏で計算している途中で何かキーを入力すると、計算が止まります。(しばらく待ってても結果が出力されないことで確認できます)

でも、計算を止めないとなぜかデッドロックする模様。はて。

import Control.Concurrent
import Control.Monad (mzero, liftM2)

main = do putStrLn "Enter number: "
          n <- getLine
          stopper <- newMVar False
          forkIO $ fib (read n) stopper
          putStrLn "Press any key to stop calculation."
          getChar
          putMVar stopper True
          putStrLn "Now thread stops."
          getChar
          return ()
fib n s = do result <- sfib n s
             print result
             putStrLn "Complete!"
             return ()
sfib :: Int -> MVar Bool -> IO (Maybe Int)
sfib n s = do s' <- readMVar s
              if s' then return mzero
                    else if n < 1 then return $ return 1
                                  else do a <- sfib (n-1) s
                                          b <- sfib (n-2) s
                                          return $ liftM2 (+) a b

止めた場合。

% ./sfib
Enter number: 
25
Press any key to stop calculation.

Now thread stops.

%

止めなかった場合。

% ./sfib
Enter number: 
25
Press any key to stop calculation.
Just 196418
Complete!

sfib: thread blocked indefinitely

%