foldlという関数を見ると、いろいろと話したくなるのがHaskellerの性なのだけど、まあすごく簡単に言うと、「昔はスペースリークの関係でfoldlではなくfoldl'を使えと言われていたけど、今はfoldlとfoldl'は同じものなのでfoldlを使えばいい」という話で、一周して意味のない話になる。
スリープソート
リストを返す版
{-# LANGUAGE BlockArguments #-}
import Control.Concurrent
import Control.Concurrent.STM
import Data.Function
sort :: [Int] -> IO [Int]
sort ns = do
c <- atomically newTChan
mapM_ (forkIO . single c) ns
threadDelay 1000000
atomically $ fix \go -> do
e <- isEmptyTChan c
if e then pure [] else (:) <$> readTChan c <*> go
single :: TChan Int -> Int -> IO ()
single c n = threadDelay (n * 1000) >> atomically (writeTChan c n)
sleep sortの単純な実装。結果はstdoutに出してる。
import Control.Concurrent
sort :: [Int] -> IO ()
sort ns = do
mapM_ (forkIO.single) ns
threadDelay 1000000
single :: Int -> IO ()
single n = threadDelay (n * 1000) >> print n