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.
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:
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.
Mit Monad-Transformatoren brauchen Sie nur
Ändern Sie die Funktionssignatur von Int -> Maybe Int
nach
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 .
Führen Sie die Funktion mit runMaybeT
Ein minimales Beispiel wäre:
%Vor%dann,
%Vor%Was Sie daraus bekommen, wäre von der Art:
%Vor%Tags und Links haskell