1

I would like to input a string from the console and output a JSON string.

{-# LANGUAGE OverloadedStrings #-}

module Main where
  
import Data.Aeson
import Data.Map.Strict
                
main :: IO ()
main = interact $ encode

This code fails. Of course, I see encode has type ToJSON a => a -> Data.ByteString.Lazy.Internal.ByteString and interact' takes String -> String, but that's the reason I'm using OverloadedStrings.

How can I solve this problem ? Perform a cast to String ?

sjakobi
  • 3,546
  • 1
  • 25
  • 43
F. Zer
  • 1,081
  • 7
  • 9
  • 2
    `OverloadedString`s only works for string *literals*. – Willem Van Onsem Mar 06 '22 at 19:25
  • Fantastic. Thank you, @WillemVanOnsem. Could you please give me a suggestion for the solution ? – F. Zer Mar 06 '22 at 19:26
  • What are you even trying to accomplish here? What behaviour should this program have? – leftaroundabout Mar 06 '22 at 19:33
  • Thank you for your comment, @leftaroundabout. I made a minimal example to illustrate my question. In the end, this program should read string from the terminal, parse each line into a `Map String String` type and encode it as a JSON string. – F. Zer Mar 06 '22 at 19:35
  • @F.Zer: exactly how would the `Map String String` "input format" look like? – Willem Van Onsem Mar 06 '22 at 19:36
  • @Willem Van Onsem I am parsing many lines of text using Hutton's parsing library. In a nutshell, each line has the format "key: value". An arbitrary line could be: "Patient: John Doe", for example. – F. Zer Mar 06 '22 at 19:39

1 Answers1

4

OverloadedStrings only works for string literals. It thus converts a "foo" expression to fromString "foo".

But you can use this to convert this to a ByteString. You can first use decodeUtf8 :: ByteString -> Text to convert the ByteString to a Text, then use the String data constructor of the Value type, and then encode the data, so:

module Main where

import Data.Aeson(Value(String), encode)
import qualified Data.ByteString as B
import Data.ByteString.Lazy(toStrict)
import Data.Text.Encoding(decodeUtf8)

main :: IO ()
main = B.interact (toStrict . encode . String . decodeUtf8)

This will thus convert the input to a JSON string literal.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • Thank you so much ! What's this `Value(String)` ? I've never seen it. – F. Zer Mar 06 '22 at 19:40
  • 1
    @F.Zer `Value(String)` will import the `String` data constructor of the `Value` type which is defined in the `Data.Aeson` module. – 4castle Mar 08 '22 at 02:59