(Wie) ist es möglich, Monaden in Scala auf eine generische Art und Weise darzustellen (wie die Monad
Typenklasse in Haskell)? Ist es irgendwie möglich, einen trait Monad
für diesen Zweck zu definieren?Monad-Eigenschaft in Scala
Antwort
Man könnte so etwas wie dies versuchen:
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
}
Sie würden natürlich definieren ähnliche implizite Objekte für andere Monade das Herz begehrt. In Haskell-Begriffen können Sie sich wie die Typklasse Monad
und MonadicOption
als eine bestimmte Instanz dieser Typklasse vorstellen. Die implizite Konvertierung monadicSyntax
demonstriert einfach, wie diese Typklasse verwendet werden könnte, um Scalas for
-comprehensions mit allem zu ermöglichen, das die Monad
typeclass erfüllt.
Im Allgemeinen sind die meisten Dinge in der Scala-Standardbibliothek, die flatMap
implementieren, Monaden. Scala definiert keine generische Monad
Typklasse (obwohl das sehr nützlich wäre). Stattdessen stützt es sich auf einen syntaktischen Trick des Parsers, um die Verwendung von for
-comprehensions mit irgendetwas zu ermöglichen, das die entsprechenden Methoden implementiert. Insbesondere sind diese Methoden map
, flatMap
und filter
(oder foreach
und filter
für die Imperativform).
Sie können das scalaz Projekt interessant finden; es hat neben einer Implementierung von Monaden noch viele andere (funktionale) Sachen.
Scala erreicht eine ähnliche Leistung wie die Haskell-Typklassen durch Verwendung impliziter Parameter, insbesondere von Ansichtsgrenzen und Kontextgrenzen. Sie können solche Dinge besonders auf Scala 2.8 mit Merkmalen wie Ordering
und Numeric
sehen.
Das heißt, schauen Sie sich das Projekt Scalaz. Es hat Monaden, Funktoren, Pfeile ... den ganzen Shebang.
Werfen Sie einen Blick auf http://www.scala-lang.org/api/current/index.html#scala.collection.generic.FilterMonadic. Eine Fall-Klasse ist bereits in die Sprache gebaut und ausgiebig durch sammlungen ...
http://www.codecommit.com/blog/ruby/monads-are-not-metaphors
Hier ist ein nützlicher und recht langer Artikel über das Monad Muster und deren Umsetzung in Scala von Daniel verwendet, die die akzeptierten schrieben Antwort für diese Frage.
(Für diejenigen, die über die mystischen Wege der Stackoverflow Website-Suche auf dieser „alte“ Frage stolpern.)
- 1. Scala AST in Scala
- 2. Anfänger: Scala-Typ Alias in Scala 2.10?
- 3. Vermeidung Scala Speicherlecks - Scala Bauer
- 4. Typ in Scala
- 5. Bitstream-Bibliothek in Scala
- 6. BitSet Speichernutzung in Scala
- 7. Thread.sleep in Scala Schauspieler
- 8. POS-Tagging in Scala
- 9. Klassenalias in scala
- 10. Verschachtelte Iteration in Scala
- 11. Comonad Beispiel in Scala
- 12. eine Falte in Scala
- 13. Benchmarking in scala
- 14. Bitfelder in Scala
- 15. Auswahl Sortierung in Scala
- 16. Hdfs Dateiliste in Scala
- 17. MinMax Normalisierung in Scala
- 18. SAXParseException in Scala vermeiden
- 19. Teilfunktionen in Scala
- 20. Zahlenformatierung in Scala?
- 21. Int Division in Scala
- 22. Typedef in Scala
- 23. Lazy Funktionsdefinitionen in Scala
- 24. Scala Refactoring in IDEA
- 25. Proxies/Delegierten in Scala
- 26. Persistente Datenstrukturen in Scala
- 27. Optionen in scala reduzieren?
- 28. Trimmen Saiten in Scala
- 29. Zurück in Scala
- 30. Koaleszierende Optionen in Scala
Danke, das war genau das, was ich suchte. Ich wollte nur generische Monad-Funktionen und Transformer allgemein definieren ... – Dario
Sie werden das wirklich nicht für etwas wirklich verwenden, oder? :-) Im Ernst, ich arbeite seit einiger Zeit mit Scala, und ich habe festgestellt, dass viele Fälle, in denen Haskell die Monad-Klasse benutzt, in Scala wegen Charakterzügen und Subtyping nicht vorkommen. Die oben angegebene Typenklasse wäre zwar nicht cool, aber sicherlich nicht die idiomatische Lösung von Problemen in Scala. –
Aber sie kommen auf. Sie kommen die ganze Zeit auf. Ein paar Mal am Tag möchte ich 'liftA2' oder' sequenceA'. Zugegeben, diese erfordern nur Applicative statt Monad, aber wenn diese nicht in Ihrer Programmierung auftauchen, dann müssen Sie etwas sehr einfaches schreiben. – Apocalisp