softshipper
softshipper

Reputation: 34119

Couldn't match type ‘[Char]’ with ‘Data.Text.Internal.Text’

I am trying to figure out, how to build JSON in Haskell with the following example:

module Main where


import GHC.Exts
import Data.Aeson
import qualified Data.Text.Lazy.IO as T
import qualified Data.Text.Lazy.Encoding as T

val :: Value
val = Object $ fromList [
  ("numbers", Array $ fromList [Number 1, Number 2, Number 3]),
  ("boolean", Bool True) ]

main :: IO ()
main = T.putStrLn . T.decodeUtf8 . encode $ val

When I tried to compile, the compiler complains:

    • Couldn't match type ‘[Char]’ with ‘Data.Text.Internal.Text’
      Expected type: Item Object
        Actual type: ([Char], Value)
    • In the expression: ("boolean", Bool True)
      In the first argument of ‘fromList’, namely
        ‘[("numbers", Array $ fromList [Number 1, Number 2, ....]),
          ("boolean", Bool True)]’
      In the second argument of ‘($)’, namely
        ‘fromList
           [("numbers", Array $ fromList [Number 1, Number 2, ....]),
            ("boolean", Bool True)]’
   |
12 |   ("boolean", Bool True) ]
   |   ^^^^^^^^^^^^^^^^^^^^^^

Upvotes: 7

Views: 2535

Answers (2)

Karol Samborski
Karol Samborski

Reputation: 2965

The error you get is about wrong string representation. Haskell has many of them, e.g. ByteString (strict or lazy), Text (strict or lazy), String (alias for [Char]). The last one is the default and also the one you should avoid most of the time.

Aeson library uses the Text as string representation. You can fix your code using T.pack before the string (to convert it to Text), like this:

val :: Value
val =
  Object $
  fromList
    [ (T.pack "numbers", Array $ fromList [Number 1, Number 2, Number 3])
    , (T.pack "boolean", Bool True)
    ]

Or you can just enable OverloadedStrings extension. When it's on then Haskell compiler will try to figure out which string representation it should use. Just put {-# LANGUAGE OverloadedStrings #-} at the top of your file and it should work.

Upvotes: 7

Sibi
Sibi

Reputation: 48766

You need to put OverloadedStrings extension on top of the file:

#!/usr/bin/env stack
-- stack script --resolver lts-12.7
{-# LANGUAGE OverloadedStrings #-}

import Data.Aeson
import qualified Data.Text.Lazy.Encoding as T
import qualified Data.Text.Lazy.IO as T
import GHC.Exts

val :: Value
val =
  Object $
  fromList
    [ ("numbers", Array $ fromList [Number 1, Number 2, Number 3])
    , ("boolean", Bool True)
    ]

main :: IO ()
main = T.putStrLn . T.decodeUtf8 . encode $ val

And on executing them:

$ stack fuse.hs
{"boolean":true,"numbers":[1,2,3]}

To understand the reasons on why that makes it work, refer to this answer.

Upvotes: 11

Related Questions