En el proceso de escribir una simple calculadora RPN, tengo los siguientes alias de tipo:plegable flatMap/vinculación a través de una lista de funciones (también conocido como nombre a ese Combinator!)
type Stack = List[Double]
type Operation = Stack => Option[Stack]
... y he escrito una línea de aspecto curioso de código Scala:
val newStack = operations.foldLeft(Option(stack)) { _ flatMap _ }
Esto toma una inicial stack
de los valores y aplica una lista de operations
a la pila. Cada operación puede fallar (es decir, produce un Option[Stack]
) así que las secuencia con flatMap
. Lo que es algo inusual acerca de esto (en mi opinión) es que estoy doblando una lista de funciones monádicas, en lugar de doblar sobre una lista de datos.
Quiero saber si hay una función estándar que capture este comportamiento de "doblar". Cuando estoy tratando de jugar el "nombre que Combinator" del juego, Hoogle suele ser mi amigo, por lo que intentó el mismo ejercicio mental en Haskell:
foldl (>>=) (Just stack) operations
Los tipos aquí son:
foldl :: (a -> b -> a) -> a -> [b] -> a
(>>=) :: Monad m => m a -> (a -> m b) -> m b
por lo que el tipo de mi combinador misterio foldl (>>=)
, después de hacer los tipos de foldl
y (>>=)
línea de arriba, debe ser:
mysteryCombinator :: Monad m => m a -> [a -> m a] -> m a
... que es otra vez lo que había esperar. Mi problema es que al buscar en Hoogle una función con ese tipo no se obtienen resultados. Intenté algunas otras permutaciones que pensé que podrían ser razonables: a -> [a -> m a] -> m a
(es decir, comenzando con un valor no monádico), [a -> m a] -> m a -> m a
(es decir, con argumentos volteados), pero tampoco tuve suerte. Entonces mi pregunta es, ¿alguien sabe un nombre estándar para mi misterioso combinador "doblar"?
Recomendaría no usar esta implementación del combinador; Creo que la mayoría de las implementaciones de '(>> =)' están destinadas a ser utilizadas de una forma asociativa correcta, por lo que hay buenas posibilidades de que esto pueda causar problemas de rendimiento (como una pila asociativa izquierda de '(++)' s hace). – ehird
@ehird - No creo que entiendo ... ¿Cómo podría proponer aplicar una secuencia de operaciones '[a -> ma]', en orden de izquierda a derecha, a algunas 'a' iniciales o' ma 'valor? Además, tenga en cuenta que no estoy haciendo una pregunta específica del idioma; las características de rendimiento diferirán entre Scala y Haskell (podría suponer que estoy usando 'foldl'' para rigor). Todo lo que realmente me importa es si esto tiene un nombre bien conocido. – mergeconflict
Creo que el punto de @ ehird es que 'foldr' puede ser más eficiente ya que puede detenerse temprano (en el caso de un' Nothing', por ejemplo). –