无法使用 IO Monad 打印到文件

Can not print to file using IO Monad

你好,我已经完成了 JSon 类型,我正在尝试将其写入文件。 我可以从序曲中做到这一点,但在使用 IO Monad.I 时我无法做到这一点得到以下 error:

 Main.hs:13:24: error:
    * Couldn't match type `Char' with `[Char]'
      Expected type: String
        Actual type: Char
    * In the second argument of `writeFile', namely `val'
      In a stmt of a 'do' block: writeFile out val
      In the expression:
        do val <- renderJValue sample
           writeFile out val
   |
13 |          writeFile out val
   |                        ^^^

主要

 module Main where
        import Jlib
        import Put
        import Data.Typeable

        import System.Environment

        out="data.txt"

        main::IO()
        main=do
             val<-renderJValue sample
             writeFile out val

为什么这在 IO Monad 中不起作用,因为 renderJValue sample 在序曲中工作正常。

Jlib.hs

data JValue=JString String
                |JNumber Double
                |JBool Bool
                |JNull
                |JObject [(String,JValue)]
                |JArray [JValue]
                deriving (Eq,Ord,Show)

Put.hs

sample=JArray[
                    JObject [("name",JString "adita"),("age",JNumber 13)],
                    JObject [("name",JString "dan"),("kids",JNumber 3)] ,
                    JNumber 3,
                    JBool False,
                    JString "Howdy"
                    ]

P.S renderJValue returns 一个字符串

P.S: 如果我开始前奏,我加载模块并渲染它工作的值:

Prelude System.Environment Put> :load Put
Ok, two modules loaded.
Prelude System.Environment Put> renderJValue sample
"[{name:adita,age:13.0},{name:dan,kids:3.0},3.0,False,Howdy]"

你在这里使用 renderJValue sample 就好像它是一个 IO String:

main :: IO()
main=do
     <b>val <- renderJValue sample</b>
     writeFile out val

但实际上(假设它是一个类似于this one的函数)一个签名为renderJValue :: JValue -> String的函数。所以没有 IO 涉及。在那种情况下,我们不使用箭头符号。

我们可以调用函数“inline”:

main :: IO()
main = do
     writeFile out <b>(renderJValue sample)</b>

甚至更短:

main :: IO()
main = writeFile out (renderJValue sample)

但是如果表达式很长,这会变得很丑陋。在这种情况下,我们可以决定使用 let 语句。

您可以通过删除 putStrLn:

来解决这个问题
main :: IO()
main = do
    <b>let</b> val <b>=</b> renderJValue sample
    writeFile out val