История изменений
Исправление quasimoto, (текущая версия) :
(>=>) берёт по «унарной» функции слева и справа и возвращает новую «унарную» функцию (кавычки, так как m x может быть функциональным типом):
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
сравним с обычной композицией функций:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
то есть flip (>=>) == (<=<) ~~ (.). ~~ означает эквивалентность в случае identity monad — ((c <=< b <=< a) arg) и ((c . b . a) arg) будут одинаково вычислять всю цепочку (c (b (a arg))), у нас задача её прервать, то есть вставить проверок в каждый узел, это получается переходом к kleisli category вокруг другой монады — MaybeT IO, например.
То есть (>=>) это обобщение композиции функций.
Эти три функции:
checkFile :: FilePath -> MaybeIO FilePath
parse :: FilePath -> MaybeIO Map
checkValue :: Value -> Maybe Value
уже унарны, поэтому просто передаются. Бинарная
findVarValue :: Key -> Map -> Maybe Value
делается унарной частичным применением
findVarValue "a" :: Map -> Maybe Value
то что выходит из стрелки слева сочетается по типу со входом вправо (FilePath/FilePath, например), так же как и по монадическому типу (MaybeIO — слой с эффектами, Maybe — обычный чистый, приходится их явно смешать с помощью up).
Исходная версия quasimoto, :
(>=>) берёт по «унарной» функции слева и справа и возвращает новую «унарную» функцию (кавычки, так как m x может быть функциональным типом):
(>=>) :: Monad m => (a -> m b) -> (b -> m c) -> (a -> m c)
сравним с обычной композицией функций:
(.) :: (b -> c) -> (a -> b) -> (a -> c)
то есть flip (>=>) == (<=<) ~~ (.). ~~ означает эквивалентность в случае identity monad — ((c <=< b <=< a) arg) и ((c . b . a) arg) будут одинаково вычислять всю цепочку (c (b (a arg))), у нас задача её прервать, то есть вставить проверок в каждый узел, это получается переходом к kleisli category вокруг другой монады — MaybeT IO, например.
То есть (>=>) это обобщение композиции функций.
Эти три функции:
checkFile :: FilePath -> MaybeIO FilePath
parse :: FilePath -> MaybeIO Map
checkValue :: Value -> Maybe Value
уже унарны, поэтому просто передаются. Бинарная
findVarValue :: Key -> Map -> Maybe Value
делается унарной частичным применением
findVarValue "a" :: Map -> Maybe Value
то что выходит из стрелки слева сочетается по типу со входом вправо (FilePath/FilePath), так же как и по монадическому типу (MaybeIO — слой с эффектами, Maybe — обычный чистый, приходится их явно смешать с помощью up).