(¿Cómo) es posible representar mónadas en Scala de una manera genérica (como la clase de tipo Monad
en Haskell)? ¿Es de alguna manera posible definir un trait Monad
para este propósito?rasgo Monad en Scala
Respuesta
usted podría intentar algo como esto:
trait Monad[+M[_]] {
def unit[A](a: A): M[A]
def bind[A, B](m: M[A])(f: A => M[B]): M[B]
}
// probably only works in Scala 2.8
implicit def monadicSyntax[M[_], A](m: M[A])(implicit tc: Monad[M]) = new {
private val bind = tc.bind(m) _
def map[B](f: A => B) = bind(f compose tc.unit)
def flatMap[B](f: A => M[B]) = bind(f)
}
implicit object MonadicOption extends Monad[Option] {
def unit[A](a: A) = Some(a)
def bind[A, B](opt: Option[A])(f: A => Option[B]) = opt flatMap f
}
Usted, por supuesto definir objetos implícitos similares para cualquier otra mónada que su corazón desea. En términos de Haskell, puede pensar en Monad
como tipo de clase y MonadicOption
como una instancia particular de esa clase de tipo. La conversión implícita monadicSyntax
simplemente demuestra cómo se podría usar esta clase de tipos para permitir el uso de las for
de Scala -comprehensiones con cualquier cosa que satisfaga la clase de tipo Monad
.
En general, la mayoría de las cosas en la biblioteca estándar de Scala que implementan flatMap
son mónadas. Scala no define una clase de tipo genérica Monad
(aunque eso sería muy útil). En cambio, se basa en un truco sintáctico del analizador para permitir el uso de for
-comprehensions con cualquier cosa que implemente los métodos apropiados. Específicamente, esos métodos son map
, flatMap
y filter
(o foreach
y filter
para la forma imperativa).
Puede encontrar el proyecto scalaz interesante; tiene muchas otras cosas (funcionales) además de una implementación de mónadas.
Scala logra una potencia similar a las clases de tipos de Haskell a través del uso de parámetros implícitos, particularmente límites de vista y límites de contexto. Puede ver tales cosas en uso particularmente en Scala 2.8, con características como Ordering
y Numeric
.
Dicho esto, mire el proyecto Scalaz. Tiene mónadas, funcionadores, flechas ... todo el shebang.
Eche un vistazo a http://www.scala-lang.org/api/current/index.html#scala.collection.generic.FilterMonadic. Una clase caso ya está integrado en el lenguaje y se utiliza extensivamente a través de las colecciones ...
http://www.codecommit.com/blog/ruby/monads-are-not-metaphors
Aquí está un artículo útil y bastante largo sobre el patrón Mónada y su aplicación en la Scala de Daniel, que escribió el aceptada respuesta para esta pregunta
(Para los que se tropiezan con esta pregunta "antigua" a través de las formas místicas de sitio de búsqueda de StackOverflow.)
- 1. Rasgo, FunciónN o Rasgo-heredando-FunciónN en Scala?
- 2. ¿Cuál es el rasgo Comparable de Scala?
- 3. Componer comportamiento rasgo en Scala en un Akka reciben método
- 4. Rasgo anidado en el constructor de clase en scala
- 5. ¿Por qué Scala no tiene una Monad de IO?
- 6. ¿Cómo se define un rasgo de paquete * privado * en Scala?
- 7. Genéricos en Scala: implementar una interfaz/rasgo dos veces?
- 8. lo que es más Scala idiomática: rasgo TraitA extiende TraitB o rasgo TraitA {auto: TraitB =>}
- 9. mixin o rasgo en F #
- 10. ¿Por qué un rasgo de Scala puede extender una clase?
- 11. Soporte de biblioteca para el rasgo NotNull de Scala
- 12. diferencia rasgo dinámico de Scala 2.9 a 2.10
- 13. Mejores prácticas de Scala: herencia de rasgo frente a enumeración
- 14. Scala println no funciona con el rasgo de aplicación
- 15. ¿Qué significa instanciar un rasgo?
- 16. list monad transformer
- 17. ¿Qué es un rasgo sellado?
- 18. Ayúdeme a entender este código de Scala: Scalaz IO Monad e implica
- 19. Llamar a un método en la superclase en un rasgo auto tipado en scala
- 20. ¿Cómo consigo la clase en tiempo de ejecución de un tipo parametrizado en un rasgo Scala
- 21. ¿Cómo creo una instancia de un rasgo en un método genérico en scala?
- 22. Diferencia entre la clase abstracta y Rasgo
- 23. IO dentro de Get Monad
- 24. Usando la Lógica Monad en Haskell
- 25. ¿Qué significa "rasgo A <: B"?
- 26. ¿Debo crear un nuevo objeto para mezclar en un rasgo de Scala?
- 27. ¿Es posible cambiar la varianza de una clase/rasgo base en Scala?
- 28. Usando el constructor scala para establecer la variable definida en el rasgo
- 29. Scala - mezcla en un rasgo con sus importaciones (importaciones que heredan)
- 30. Scala: Obtener el nombre de la clase del rasgo se mezcla en
Gracias, esto era exactamente lo que estaba buscando. Solo quería definir funciones genéricas de mónada y transformadores de forma general ... – Dario
En realidad, no va a usar esto para nada real, ¿verdad? :-) En serio, he estado trabajando con Scala por un tiempo, y he descubierto que muchos casos en los que Haskell usaría la clase de Monad simplemente no aparecen en Scala debido a los rasgos y la subtipificación. La clase de tipos dada arriba, aunque es genial, ciertamente no sería la manera idiomática de resolver problemas en Scala. –
Pero aparecen. Aparecen todo el tiempo. Un par de veces al día, quiero 'liftA2' o' sequenceA'. De acuerdo, estos solo requieren de Applicative en lugar de Monad, pero aún así, si estos no aparecen en su programación, entonces debe escribir algo muy simple. – Apocalisp