Интуитивно, он используется для «вставки» исключения ioError e
в нужное место, детерминистически c.
Рассмотрим M = catch (threadDelay 1000000) someHandler
. У нас есть оба:
M = Ea[M]
where Ea[x] = x
M = Eb[M']
where Eb[x] = catch x someHandler
M' = threadDelay 1000000
без побочного условия, у нас было бы два отдельных операционных шага, делая семантику недетерминированной c:
{throwTo t e}s | {M}t ==> {return ()}s | {Ea[ioError e]}t
= {return ()}s | {ioError e}t
{throwTo t e}s | {M}t ==> {return ()}s | {Eb[ioError e]}t
= {return ()}s | {catch (ioError e) someHandler}t
В первом случае ошибка не ловится, в последнем она есть. Боковое условие гарантирует, что только последний является допустимым шагом.
Привязка также существует, чтобы избежать замены всего в:
M = catch (threadDelay 1000000) someHandler >>= something
Здесь, если вам требуется только "M
, а не поймать ", вы можете снова выбрать M = Ea[M]
и заменить весь код. Вместо этого боковое условие заставляет вас выбрать
Ec[x] = catch x someHandler >>= something
и вставить ioError e
в правильное место внутри catch
.