Не удается распечатать в файл с помощью IO Monad

Здравствуйте, я сделал мой тип 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
   |                        ^^^

Главный

 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"
                    ]

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]"

1 ответ

Решение

Вы здесь используете renderJValue sample как будто это IO String:

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

Но на самом деле это (если это функция, аналогичная этой) функция с сигнатурой renderJValue :: JValue -> String, Так нет IO вовлечен. В этом случае мы не используем обозначение стрелки.

Мы можем вызвать функцию "inline":

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

или даже короче

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

Но если выражение довольно длинное, это может стать довольно уродливым. Мы можем решить использовать let заявление в этом случае.

Вы можете решить эту проблему, удалив putStrLn:

main :: IO()
main = do
    let val = renderJValue sample
    writeFile out val
Другие вопросы по тегам