2009-10-03 3 views
7

Beim Lernen über neue Programmierobjekte folge ich normalerweise einem Muster: Ich lese darüber, ich verstehe es, und dann code ich ein paar Beispiele, um sicherzustellen, dass ich wirklich bekommen.auf der Suche nach Lernübung: Implementieren Sie diese Monaden

Ich habe viel über Monaden gelesen, und ich bin zuversichtlich, dass ich verstehe und sie bekomme. Ich bin jetzt in einem Stadium, in dem ich wirklich ein paar Monaden kodieren möchte, um mein Verständnis zu verfestigen, und wirklich herauszufinden, was es braucht, um bind für eine Vielzahl von Typen zu implementieren.

Das Problem ist, dass ich nicht an viele offensichtliche Monaden denke zu implementieren, also bin ich auf der Suche nach Empfehlungen. Am liebsten hätte ich eine Liste von Empfehlungen, mit einigen einfachen und einigen nicht so einfachen.

Ich erkenne auch, dass während Monaden verwendet werden, um Nebenwirkungen in funktionalen Programmen einzukapseln, sie auch allgemeiner als das sind. Also, ich möchte, dass die Empfehlungen Monaden enthalten, die sowohl Nebenwirkungen als auch einige allgemeine einschließen.

Danke!

(als Randnotiz: Ich werde mit f # arbeiten, um dies zu tun, aber ich denke, dass diese Frage für jede funktionale Sprache gelten könnte).

Antwort

5

Ich denke, dass der Katalog in All About Monads ein guter Start ist (die Fortsetzung Monade ist tatsächlich nützlich für Katamorphismen, siehe beispielsweise here); zusätzlich parsers und möglicherweise transactional effects. Async ist ein weiterer netter zu versuchen, auf eigene Faust zu implementieren (logisch single-threaded Code, der über verschiedene tatsächliche Threads hüpft, um nicht zu blockieren).Und die zugrunde liegende Monade der Reactive Framework sieht wie eine gute fortgeschrittene Herausforderung aus.

2

Die Liste der Daten/Berechnungen, die einer Art monadischen Gesetz folgen, ist extrem reich.

Es reicht von Listen über optionale Daten ('a option in F #), Fortsetzungen und Multithreading bis hin zu hochkomplexen Dingen wie Parsern.

Beginnen Sie einfach, einige von ihnen zu implementieren. Grund exercies:

// Identity monad 

let something = ident { 
    let! value = id 42 
    return value 
} 

let somethingelse = ident { 
    let! value = something 
    let! otherValues = id 40 
    return value + othervalue 
} 


// Implement maybe for 'a option 
let sum = maybe { 
    let! a = maybeInputNumber("a") 
    let! b = maybeInputNumber("b") 
    let! c = maybeInputNumber("c") 
    return a + b + c 
} 

match sum with 
| None -> ... 
| Some(n) -> ... 

Sie können auch Ihr Verständnis erhöhen, indem ein litte bit mit Hilfsfunktionen und explizite monadischen Syntax zu spielen.

// Given m >>= f for m.Bind(f) 

let (>-) f monad = monad >>= (fun k -> return(f x)) 

// What's this? 
let res = ((+) 1) >- [1..10] 

Wenn Sie einige komplexe Beispiele wollen, werfen Sie einen Blick auf monadic parser combinators. Dies ermöglicht es Ihnen, komplexe Rekursiver Abstieg in Ebene F # (Werfen Sie einen Blick auf die FParsec -Project)

let parseVector = parser { 
    do! ignore $ char '(' 
    let! [x;y;z] = sepBy parseNumber "," 
    do! ignore $ char ')' 
    return new Vector(x, y, z) 
} 

Eine einfache Implementierung für diese auf folgende Arten basiert zu implementieren:

type 't Computation = 
    | Error of ... 
    | Result of 't 

type Input  = char list 
type 'a Parser = Input -> (('a * Input) Computation) 

Versuchen Sie, implementieren binden und Rückkehr ;-)

und als allgemeiner Tipp: Wenn Sie wirklich Monaden in ihrer natürlichen Umgebung verstehen wollen, Sie‘ Ich muss Haskell verwenden ;-) In F # gibt es nur Berechnungsausdrücke, nur ein vages Analogon, aber Haskell führt eine allgemeine Schnittstelle für jede monadische Berechnung ein. Perfekt, um sie auszuprobieren!

1

Obwohl ich denke, es gibt keine Herausforderung die Tatsache, dass Haskell die natürliche Sprache ist, um über Monaden zu lernen, finde ich, dass eine sehr hilfreiche Übung ist, monadische Berechnungen zu einer Sprache zu bringen, die nicht out of the box hat Haskell-like super glatte Unterstützung für sie. Es ist in jeder Sprache möglich, und in jeder vernünftigen Sprache wird es wahrscheinlich möglich sein, kreativ zu sein und sie wirklich gut aussehen zu lassen - dabei viel zu lernen! Ich habe zum Beispiel eine coole monadische Syntax für Python (um Valued Lessons, denke ich) gesehen.

Es gibt auch Clojures clojure.contrib.monads-Bibliothek, die schöne Einrichtungen für die Verwendung von Monaden in einem Lisp bietet. Der Versuch, einige seiner Funktionen nachzubauen, könnte ziemlich lehrreich sein. Es kann auch hilfreich sein, die allgemeinen Muster von den Einzelheiten der Haskell-Syntax abzutrennen, wenn sie manchmal anstelle von Haskell verwendet wird (obwohl sie sind, ganz sicher, um sicher zu sein).

Verwandte Themen