2017-02-22 3 views
0
Ausführung

Ich habe einAktion IO in anderen Monaden verschachtelt nicht

foobar :: IO (ParseResult [(String,String)]) 

parseResult eine Monade hier definiert ist: https://hackage.haskell.org/package/haskell-src-exts-1.13.5/docs/Language-Haskell-Exts-Parser.html#t:ParseResult

ich diese Strings nehmen wollen und schreibt sie in eine LaTeXT m() in definierten https://hackage.haskell.org/package/HaTeX-3.17.1.0/docs/Text-LaTeX-Base-Writer.html

Wenn diese Funktion ausgeführt wird, wird keine Datei erstellt.

writeReport2 :: [Char] -> IO (ParseResult (IO())) 
writeReport2 name = do x <- foobar 
         return $ do y <- x 
            return $ do z <- (execLaTeXT.docAndGraph) y 
               renderFile fileName z 
    where 
    fileName = name ++ ".tex" 

jedoch der Code:

writeReport :: t -> LaTeXT IO a -> IO() 
writeReport name report = createLatex >>= renderFile fileName 
    where 
    createLatex = execLaTeXT report 
    fileName = "AAAAA" ++ ".tex" 


testFoo = [(" | HaskellExample Example File\n | Two examples are given below:\n\n >>> fib 10\n 55\n\n >>> putStrLn \"foo\\nbar\"\n foo\n bar ","fib :: Int -> Int"),("\n | This is a thing: ","fib = undefined"),("\n | This is a thing:\n","fibar :: String -> Float")] 

itWorks = writeReport "AAAA.txt" $ docAndGraph testFoo 

eine neue Datei erstellen wird.

Beide Arten von Codetypen prüfen.

Antwort

3

Ich könnte writeReport2 arbeiten ohne Änderung.

Ich denke, was Ihr Problem sein könnte, ist die verschachtelte IO Aktion im Rückgabewert von writeResport2!

Um die verschachtelten IO Aktionen glätten, hatte ich die Funktion verwenden join :: Monad m => m (m a) -> m a from Control.Monad:

main :: IO() 
main = join $ fromParseResult <$> writeReport2 "test" 

Hier ist meine komplette Code:

{-# LANGUAGE OverloadedStrings #-} 

module Main where 

import   Language.Haskell.Exts.Parser 
import   Text.LaTeX.Base.Writer 
import   Text.LaTeX 
import   Data.String 
import   Control.Monad 

foobar :: IO (ParseResult [(String, String)]) 
foobar = return (ParseOk testFoo) 

testFoo = [ (" | HaskellExample Example File\n | Two examples are given below:\n\n >>> fib 10\n 55\n\n >>> putStrLn \"foo\\nbar\"\n foo\n bar " 
      , "fib :: Int -> Int" 
      ) 
      , ("\n | This is a thing: ", "fib = undefined") 
      , ("\n | This is a thing:\n", "fibar :: String -> Float") 
      ] 

docAndGraph :: Monad m => [(String, String)] -> LaTeXT m() 
docAndGraph x = do 
    documentclass [] article 
    document $ 
     raw (fromString (show x)) 

writeReport2 :: [Char] -> IO (ParseResult (IO())) 
writeReport2 name = do 
    x <- foobar 
    return $ do 
     y <- x 
     return $ do 
      z <- (execLaTeXT . docAndGraph) y 
      renderFile fileName z 
    where 
    fileName = name ++ ".tex" 

main :: IO() 
main = join $ fromParseResult <$> writeReport2 "test" 

Laden in GHCi:

$ stack ghci 
io-action-nested-in-other-monads-not-executing-0.1.0.0: initial-build-steps (exe) 
Configuring GHCi with the following packages: io-action-nested-in-other-monads-not-executing 
Using main module: 1. Package `io-action-nested-in-other-monads-not-executing' component exe:io-action-nested-in-other-monads-not-executing with main-is file: /home/sven/dev/stackoverflow-questions/io-action-nested-in-other-monads-not-executing/src/Main.hs 
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help 
Loaded GHCi configuration from /home/sven/.ghc/ghci.conf 
[1 of 1] Compiling Main    (/home/sven/dev/stackoverflow-questions/io-action-nested-in-other-monads-not-executing/src/Main.hs, interpreted) 
Ok, modules loaded: Main. 
Loaded GHCi configuration from /tmp/ghci22616/ghci-script 

Und runnin g es:

λ main 

erstellt diese Datei:

$ cat test.tex 
\documentclass{article}\begin{document}[(" | HaskellExample Example File\n | Two examples are given below:\n\n >>> fib 10\n 55\n\n >>> putStrLn \"foo\\nbar\"\n foo\n bar ","fib :: Int -> Int"),("\n | This is a thing: ","fib = undefined"),("\n | This is a thing:\n","fibar :: String -> Float")]\end{document}%                   

Ich weiß es nicht der Umfang der Frage, aber man konnte die verschachtelten IO umgehen, wenn Sie möchten, indem doinf dies, zum Beispiel:

writeReport3 :: [Char] -> IO() 
writeReport3 name = do 
    let fileName = name ++ ".tex" 
    x <- foobar 
    case x of 
     ParseOk y -> do 
     z <- execLaTeXT (docAndGraph y) 
     renderFile fileName z 
     ParseFailed _ _ -> 
     return() 

main :: IO() 
main = writeReport3 "test" 
+0

Haben Sie zufällig eine Erklärung, warum die Verschachtelung die E/A-Aktion nicht ausführt? – LambdaScientist

+0

http://stackoverflow.com/questions/42404258/why-will-a-io-nested-in-other-monads-not-execute-is-there-a-way-to-force-them-t/42404828 # 42404828 – LambdaScientist