Mehrere Monaden in einem Do-Block

8

Ich versuche gerade, Haskell zu lernen, und ich kann das Konzept, nur eine einzige Monade im Do-Block zu verwenden, wirklich nicht verstehen. Wenn ich foo :: Int -> Maybe Int habe und in dieser Funktion zB die Funktion hIsEOF :: Handle -> IO Bool verwenden möchte. Kann mir bitte jemand ein grundlegendes Beispiel erklären, wie würde ich hIsEOF verwenden und könnte irgendwie mit Bool arbeiten?

Ich habe versucht, hier und bei Google zu suchen, aber ich stoße immer auf etwas fortgeschrittenes Zeug, in dem im Grunde niemand erklärt, wie, geben sie nur Ratschläge, wie man es direkt in den Code von OP einfügt. Ich habe Monadetransformatoren gesehen, die in diesen Threads erwähnt wurden, aber selbst nachdem ich nur wenige Ressourcen gelesen habe, kann ich nicht den richtigen Weg finden, wie man sie benutzt.

    
Marek Milkovič 24.02.2016, 02:59
quelle

2 Antworten

7

Die kurze Antwort ist nein. Die Notation basiert auf zwei Dingen:

%Vor%

Beachten Sie in >>= , dass Sie zwar mit zwei verschiedenen inneren Typen arbeiten können ( a und b ), aber nur mit einem äußeren Typ, einer Monade ( m ). Sowohl m a als auch a -> m b sind die gleichen Monaden.

Die längere Antwort ist, dass Sie sie in die gleiche Monade konvertieren müssen. Zum Beispiel kann Maybe wie folgt in IO konvertiert werden:

%Vor%

Im Allgemeinen können Monaden jedoch nur in Ausnahmefällen ineinander umgewandelt werden.

Warum funktioniert >>= nur mit einer Monade? Schauen Sie sich doch das an. Es ist definiert , um mit einer einzigen Monade gleichzeitig arbeiten zu können, und do-notation ist definiert um mit >>= zu arbeiten. Die Gründe, warum diese Definition gewählt wurde, sind etwas kompliziert, aber ich kann sie bearbeiten, wenn jemand möchte.

Sie könnten Ihr eigenes >>= erstellen, das mit mehreren Monaden funktioniert, und dann wiederverwendbare Syntax , aber das wäre wahrscheinlich schwer.

    
PyRulez 24.02.2016, 03:35
quelle
11

Mit Monad-Transformatoren brauchen Sie nur

  1. Ändern Sie die Funktionssignatur von Int -> Maybe Int nach

    %Vor%
  2. heben alle E / A-Aktionen im Block do an (oder liftIO in diesem Fall). Siehe hier, warum Sie dieses Heben benötigen und was genau es tut .

  3. Führen Sie die Funktion mit runMaybeT

  4. aus

Ein minimales Beispiel wäre:

%Vor%

dann,

%Vor%

Was Sie daraus bekommen, wäre von der Art:

%Vor%     
behzad.nouri 24.02.2016 04:17
quelle

Tags und Links