haskell

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) ]
   |   ^^^^^^^^^^^^^^^^^^^^^^

Solution

  • 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.