Синтаксис Haskell,
tick x = ((), x+1)
unitState a x = (a, x)
bindState m k = uncurry k . m -- StarOp for State
bindState tick (\() -> m) =
= uncurry (\() -> m) . (\x -> ((), x+1))
= (\y -> uncurry (\() -> m) ( (\x -> ((), x+1)) y))
= (\y -> uncurry (\() -> m) ((), y+1) )
= (\y -> (\() -> m) () (y+1) )
= (\y -> m (y+1) )
bindState m (\() -> tick) =
= uncurry (\() -> tick) . m
= uncurry (\() -> (\x -> ((), x+1))) . m
= uncurry (\() x -> ((), x+1)) . m
= (\y -> uncurry (\() x -> ((), x+1)) (m y))
= (\y -> let ((),z) = m y in ((), z+1))
Эти два значения будут одинаковыми, только если m y
возвращает ((),z)
, так что m (y+1)
возвращает ((),z+1)
(т.е. m y
добавляет только некоторые фиксированная сумма до начального состояния y
, которая не зависит от y
).
Так что я не вижу проблемы с типами, но это Engli sh Значение фразы также ускользает от меня.
Кстати, предложенный в статье способ добавления "количества выполнений" к своему монадическому c оценщику путем замены этого unitState
на unitState a x = (a, x+1)
, по сути, сделает его недопустимым монада, потому что этот новый unitState
не будет тождеством.
Типы:
tick :: M ()
bindState :: M a -> (a -> M b) -> M b
(\() -> tick) :: () -> M ()
bindState (tick :: M ()) ((\() -> m) :: () -> M b ) :: M b
bindState (m :: M ()) ((\() -> tick) :: () -> M ()) :: M ()
Так что единственное, что с типами это то, что m
должно быть m :: M ()
не общее M b
, как мы уже видели с расширениями выше.