The non-termination is (probably) due to the fact that you can have uninterruptible threads in ghc. If a thread never allocates it will never be preempted. :(
-- Lennart On 7/24/07, Dan Weston <[EMAIL PROTECTED]> wrote: > > I am trying to get my feet wet with Haskell threads with the following > problem, inspired by a recent post > (http://www.haskell.org/pipermail/haskell-cafe/2007-July/029408.html) > saying that: > > > Since there's no way to have a function be lazy in both arguments, the > > implicit convention is to make functions strict in the first arguments > > and, if applicable, lazy in the last arguments. In other words, the > > convention is > > > > True || _|_ = True but not _|_ || True = True > > > > 1 + _|_ = Succ _|_ but not _|_ + 1 = Succ _|_ > > > > Regards, > > apfelmus > > Maybe not lazy in both arguments, but how about lazy in either argument? > > The idea is to fork a thread for each of the two functions, (||) and > flip (||), pick the winner, then kill off both threads. I can wrap this > up in a pure function using unsafePerformIO (given the proof obligation > that the results of both threads will always be equal where both are > defined). > > The code below seems to work, except for the following problems: > > 1) Commenting out the type annotation f :: Bool makes the program hang > 2) If I replace f = f by f = undefined, I get an annoying print of > "LazyOr: Prelude.undefined" before it returns the correct value. > > Does anyone know why the type annotation is needed in #1, and/or how to > suppress the error message in #2? > > Dan Weston > > ----------------------------------------------------------- > import Control.Monad(when) > import Control.Concurrent(forkIO,killThread) > import Control.Concurrent.Chan(newChan,readChan,writeChan,isEmptyChan) > import Foreign(unsafePerformIO) > > f :: Bool > f = f > > main = putStrLn . show $ lazyBinaryOp (||) f True > > lazyBinaryOp p x y = unsafePerformIO $ do > c <- newChan > p2 <- forkIO (lazyBinaryOpThread c p x y) > p1 <- forkIO (lazyBinaryOpThread c p y x) > z <- readChan c > killThread p1 > killThread p2 > return z > > where > > lazyBinaryOpThread c p x y = do > case (p x y) of True -> writeChan c True > False -> writeChan c False > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-cafe >
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe