![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Предыстория: 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 с сохранением результата через какую нибудь изменяемую переменную. Ленивый - чтобы не зациклилось, сохранять результат - чтобы не перезапускалось.
no subject
Date: 2009-04-06 06:07 pm (UTC)Где ИРЛ может встретиться такая извращённая композиция вычислений?
no subject
Date: 2009-04-06 07:55 pm (UTC)В исходной статье (http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.6.5172) на эту тему первые примеры как раз оттуда.