fixIO

Apr. 6th, 2009 07:13 pm
lomeo: (лямбда)
[personal profile] lomeo
Предыстория: http://thesz.livejournal.com/950788.html?thread=7471620#t7471620

Т.е. предполагалось, что любой mdo можно развернуть в letrec (т.е. do без mfix).

Однако, простой пример
mdo
    tid1 <- forkOS (print tid2)
    tid2 <- forkOS (print tid1)
    return ()

будет в зависимости от настроения то выводить ThreadId, то показывать <<loop>>. Всё потому, что для хранения переменной используется IORef. Можно переписать mfix для IO, используя MVar:
newtype MyIO a = MyIO { runMyIO :: IO a }
    deriving (Functor, Monad, MonadIO)

instance MonadFix MyIO where
    mfix f = MyIO $ do
        ref <- newEmptyMVar
        vars <- unsafeInterleaveIO $ takeMVar ref
        realVars <- runMyIO $ f vars
        putMVar ref realVars
        return realVars

Тогда вместо <<loop>> просто висим в ожидании MVar. Зато наш пример начинает работать по человечески всегда:
myMain :: MyIO ()
myMain = mdo
    tid1 <- liftIO $ forkOS (print tid2)
    tid2 <- liftIO $ forkOS (print tid1)
    return ()

Какие могут быть подводные камни у такой реализации?

Ну, и самое главное. Я наконец понял, что перевести mdo в letrec не всегда возможно. Например, здесь. Если мы просто завернём все tid в монаду, то получим дли-и-и-инную цепочку thunk-ов, которую не сможем развернуть - stack overflow, однако! Если мы сделаем IO ленивым (тот же unsafeInterleaveIO), то получим многократное выполнение. Т.е. нам придётся вернуться к реализации ленивого IO с сохранением результата через какую нибудь изменяемую переменную. Ленивый - чтобы не зациклилось, сохранять результат - чтобы не перезапускалось.

Date: 2009-04-06 06:07 pm (UTC)
From: [identity profile] permea-kra.livejournal.com
*заинтересованно*
Где ИРЛ может встретиться такая извращённая композиция вычислений?

Date: 2009-04-06 07:55 pm (UTC)
From: [identity profile] thesz.livejournal.com
Моделирование аппаратуры.

В исходной статье (http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.6.5172) на эту тему первые примеры как раз оттуда.

Profile

lomeo: (Default)
Dmitry Antonyuk

December 2015

S M T W T F S
  12345
6789101112
131415 16171819
20212223242526
2728293031  

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 22nd, 2017 04:45 pm
Powered by Dreamwidth Studios