В процессе написания простого калькулятора RPN у меня есть следующие псевдонимы типов:
type Stack = List[Double]
type Operation = Stack => Option[Stack]
... и я написал любопытную строку кода Scala:
val newStack = operations.foldLeft(Option(stack)) { _ flatMap _ }
Это принимает начальный stack
значений и применяет список operations
к этому стеку. Каждая операция может потерпеть неудачу (т.е. Дает Option[Stack]
), поэтому я их упорядочиваю с помощью flatMap
. Вещь, которая несколько необычна в этом (на мой взгляд), заключается в том, что я складываю над списком монадических функций, а не сворачиваюсь над списком данных.
Я хочу знать, есть ли стандартная функция, которая фиксирует это поведение "fold-bind". Когда я пытаюсь сыграть в игру "Name That Combinator", Hoogle обычно является моим другом, поэтому я пробовал те же умственные упражнения в Haskell:
foldl (>>=) (Just stack) operations
Типы здесь:
foldl :: (a -> b -> a) -> a -> [b] -> a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
Итак, тип моего тайника foldl (>>=)
, после того, как выстроили типы foldl
и (>>=)
, должны быть:
mysteryCombinator :: Monad m => m a -> [a -> m a] -> m a
... что опять-таки мы ожидаем. Моя проблема заключается в том, что поиск Hoogle для функции с этим типом не дает никаких результатов. Я попробовал пару других перестановок, которые, как я думал, могут быть разумными: a -> [a -> m a] -> m a
(т.е. Начиная с немонодического значения), [a -> m a] -> m a -> m a
(т.е. С аргументами перевернуты), но и не повезло. Итак, мой вопрос: кто-нибудь знает стандартное имя моего тайного комбинатора "fold-bind"?