Подтвердить что ты не робот

Строгая строгая государственная монада

Строгая государственная монада определяется с помощью:

m >>= k = State $ \s ->
  case runState m s of
    (a, s') -> runState (k a) s'

Но это все еще может утешить память, потому что a и s' остаются неоцененными. Например, у нас может быть функция f, которая принимает большой объект в качестве входных данных и быстро возвращает (a, s'), но пока значение a остается неоцененным, вход в f не может быть GC'ed.

Одно потенциальное решение состоит в том, чтобы иметь f return seq a (a, s'), но это не всегда возможно, если мы используем что-то вроде MonadRandom, а состояние инкапсулировано в сторону от f. Есть версия, которая определяется следующим образом:

m >>= k = State $ \s ->
  case runState m s of
    (!a, !s') -> runState (k a) s'

Разве это уже существует в библиотеке?

4b9b3361

Ответ 1

Согласно законам тождества монады,

return a >>= const b = const b a = b

Таким образом, в частности,

return undefined >>= const b = b

Если операция >>= была строкой в ​​значении результата, это нарушило бы этот закон, поэтому вы не должны этого делать.

Предположим, что вы это сделаете:

m >>= k = State $ \s ->
  case runState m s of
    (a, !s') -> runState (k a) s'

Теперь мы сталкиваемся с другим законом идентичности:

m >>= return = m

Например,

return a >>= return = return a

Итак, если return a >>= return является строгим в состоянии, тогда мы также должны иметь return a strict в состоянии! Поэтому нам нужно переопределить return:

return a = State $ \ !s -> (a, s)

Обратите внимание, что вам действительно не нужно ничего делать; если вы хотите, вы можете использовать обычную строгую государственную монаду и писать такие вещи, как

!_ <- get

в тех точках, где вы хотите заставить состояние. Вы даже можете написать действие, чтобы сделать это:

forceState :: Monad m => StateT s m ()
forceState = get >>= \ !_ -> return ()

Изменить

Даже это определение немного странно для меня; Я ожидал бы, что лямбда заставит государство, а не case. Я не уверен, что если это не произойдет, это приведет к некоторому поломке, но это меня не удивило бы, если бы это произошло.