2017-02-22 18 views
0

У меня естьдействие IO вложенных в другие монады не выполняет

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

ParseResult монада определяется здесь: https://hackage.haskell.org/package/haskell-src-exts-1.13.5/docs/Language-Haskell-Exts-Parser.html#t:ParseResult

Я хочу взять эти строки и записать их в LaTeXT m(), определенной в https://hackage.haskell.org/package/HaTeX-3.17.1.0/docs/Text-LaTeX-Base-Writer.html

Выполнение этой функции не приводит к созданию файла.

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" 

Однако код:

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 

Будет создан новый файл.

Оба набора кода проверки типа.

ответ

3

Я мог бы получить writeReport2 без изменений.

Я думаю, что может быть вашей проблемой является вложенное действие IO в возвращаемом значении writeResport2!

Для того, чтобы сплющить вложенные IO действия, я должен был использовать функцию join :: Monad m => m (m a) -> m a from Control.Monad:

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

Вот мой полный код:

{-# 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" 

Загрузка в 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 

И runnin г это:

λ main 

Создает этот файл:

$ 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}%                   

Я знаю, что это не сфера вопроса, но вы можете обойти вложенную IO, если вы хотите, по doinf это, например:

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

У вас возникло объяснение, почему вложенность приводит к тому, что действие IO не выполняется? – 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

 Смежные вопросы

  • Нет связанных вопросов^_^