无法使用IO Monad打印到文件

Ber*_*ian 2 monads haskell do-notation

您好,我已经完成了我的JSon类型,我正在尝试将其添加到文件中.我可以从前奏中做到这一点但是在使用IO Monad时我无法做到这一点.我得到以下内容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
   |                        ^^^
Run Code Online (Sandbox Code Playgroud)

主要

 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
Run Code Online (Sandbox Code Playgroud)

为什么这在IO Monad中不起作用,因为renderJValue sample在前奏中工作正常.

Jlib.hs

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

Put.hs

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

PS renderJValue返回一个字符串

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

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]"
Run Code Online (Sandbox Code Playgroud)

Wil*_*sem 7

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

main :: IO()
main=do
     val <- renderJValue sample
     writeFile out val
Run Code Online (Sandbox Code Playgroud)

但事实上(鉴于它是一个与此类似的功能)具有签名的功能renderJValue :: JValue -> String.所以没有IO参与.在这种情况下,我们不使用箭头符号.

我们可以调用函数" inline ":

main :: IO()
main = do
     writeFile out (renderJValue sample)
Run Code Online (Sandbox Code Playgroud)

甚至更短:

main :: IO()
main = writeFile out (renderJValue sample)
Run Code Online (Sandbox Code Playgroud)

但如果表达相当长,这可能会变得非常难看.let在这种情况下,我们可以决定使用一个声明.

您可以通过删除以下内容来解决此问题putStrLn:

main :: IO()
main = do
    let val = renderJValue sample
    writeFile out val
Run Code Online (Sandbox Code Playgroud)

  • 每当`bar`在当前monad中返回*action*时使用`foo < - bar`(例如,`IO Integer`).每当`bar`执行*not*返回当前monad中的动作时(例如,`Integer`),请使用`let foo = bar`. (3认同)