Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using file name in json parsing (Haskell Aeson)

Tags:

I have no experience in Haskell. I'm trying to parse many .json files to a data structure in Haskell using aeson. However, by reasons beyond my control, I need to store the name of the file from where the data was parsed as one of the fields in my data. A simple example of what I have so far is:

data Observation = Observation { id :: Integer
                               , value :: Integer
                               , filename :: String}

instance FromJSON Observation where
  parseJson (Object v) =
    Observation <$> (read <$> v .: "id")
                <*> v .: "value"
                <*> ????

My question is: what is a smart way to be able to serialize my data when parsing a json file having access to the name of the file?

What comes in my mind is to define another data like NotNamedObservation, initialize it and then having a function that converts NotNamedObservation -> String -> Observation (where String is the filename) but that sounds like a very poor approach.

Thanks.

like image 636
Vitorqb Avatar asked Apr 20 '18 15:04

Vitorqb


1 Answers

Just make your instance a function from file path to Observation:

{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
import Data.Aeson
import qualified Data.ByteString.Lazy as LBS
import System.Environment

data Observation = Observation { ident    :: Integer
                               , value    :: Integer
                               , filename :: FilePath
                               } deriving (Show)

instance FromJSON (FilePath -> Observation) where
  parseJSON (Object v) =
    do i <- read <$> v .: "id"
       l <- v .: "value"
       pure $ Observation i l

main :: IO ()
main = do
  files <- getArgs
  fileContents <- traverse LBS.readFile files
  print fileContents
  let fs = map (maybe (error "Invalid json") id . decode) fileContents
      jsons :: [Observation]
      jsons = zipWith ($) fs files
  print jsons
like image 139
Thomas M. DuBuisson Avatar answered Sep 28 '22 08:09

Thomas M. DuBuisson