Используйте 1_
fixIO $ \rec -> newListener _eventm
Заполните _eventm
своим EventM
, и вы сможете получить доступ к прослушивателю событий, который в конечном итоге будет создан с помощью имени rec
. rec
будет результатом вызова newListener
, но его можно "использовать" до его выполнения. Я говорю «используется», потому что попытка форсировать его с помощью seq
или чего-то более сильного вызовет бесконечный цикл, но вы должны быть в порядке, делая то, что делаете.
fixIO
является обобщением fix
:
-- the essence of recursion
fix :: (a -> a) -> a
fix f = let x = f x in x
-- equivalent but less performant and less relevant
fix f = f (fix f)
-- if you have used JS's "named anonymous functions"
-- this will seem very familiar
(fix (\fact n ->
if n <= 1 then 1 else n * fact (n - 1)
)) 3 = 6
-- JS:
-- (function fact(n) {
-- if(n <= 1) { return 1; } else { return n * fact(n - 1); }
-- })(3) === 6
-- but this has more power
repeat = fix . (:)
repeat 1 = fix (1:) =
let x = 1:x in x = 1:fix (1:) = [1,1,1,1,1,1,1,1,1,1,1,1,1,1...]
fix id = let x = id x in x = let x = x in x = _|_ -- oops!
fixIO :: (a -> IO a) -> IO a
fixIO f = _ -- horrendous, unsafe code
fixIO (\xs -> return $ 1:xs) = return [1,1,1,1,1,1,1,1,1,1...]
fixIO return = fixIO (return . id) = return $ fix id = return _|_ -- oops!
Идея fix
состоит в том, чтобы сделать конечный результат функции доступным до того, как она будет фактически создана.
Идея fixIO
состоит в том, чтобы сделать конечный результат функции IO
доступным ей до того, как она будет фактически создана , а также выполнить некоторые IO
действий. Кроме того, fixIO
выполняет эти действия один раз, поэтому первое определение fix
(которое вызывает f
только один раз) более актуально, чем второе.
fixIO
, в свою очередь, является специализацией mfix :: MonadFix m => (a -> m a) -> m a
, где MonadFix
— класс монад (включая IO
с mfix = fixIO
), которые допускают такую семантику завязывания узлов. GHC поддерживает "рекурсивную do
" нотацию для любого MonadFix
:
{-# LANGUAGE RecursiveDo #-}
someCode = mdo ...
listener <- newListener _eventm -- can access listener in definition
...
-- or
someCode = do ...
rec listener <- newListener _eventm
...
person
HTNW
schedule
02.03.2018