{-# OPTIONS_GHC -Wall -fno-warn-name-shadowing #-}
{-
Parallel Fibonacci, using the Par monad, naive version.

Install:  cabal install monad-par
Compile:  ghc -O2 -rtsopts -o pfib1 pfib1.hs
Run:      ./pfib1 43  +RTS -N4 -s
-}
	

module Main where

import Control.Monad.Par.Scheds.Trace
  -- gives slightly better results than Control.Monad.Par with monad-par-0.3.4

import System.Environment

fib :: Int -> Int
fib 0 = 1
fib 1 = 1
fib n = nf1+nf2+1
        where nf1 = fib (n-1)
              nf2 = fib (n-2)
          
pfib :: Int -> Par Int
pfib n | n<=1 = return 1                    -- base case
pfib n | otherwise =
         do
              nv1 <- spawn (pfib (n-1))     -- start a parallel task & return an IVar
              nv2 <- spawn (pfib (n-2))     -- start a parallel task & return an IVar
              nf1 <- get nv1                -- get the result (when available)
              nf2 <- get nv2                -- get the result (when available)
              return (nf1+nf2+1)
	
main = do args <- getArgs
          let 
            n = read (args!!0) :: Int
            -- m = read (args!!1) :: Int
          putStr ("paralllel fib " ++ (show n) ++ " = ")
          let res = runPar $ pfib n
          putStrLn (show res)
