{-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TemplateHaskell #-} module Main where import qualified DemoPaths as Paths import DemoPaths (Month) import DayOfWeek import qualified Frames --import Frames.Streamly.Categorical () import qualified Frames.Streamly.CSV as FStreamly import qualified Frames.Streamly.InCore as FStreamly import qualified Frames.Streamly.Transform as FStreamly import qualified Frames.Streamly.TH as FStreamly import Frames.Streamly.Streaming.Class (runSafe) import Frames.Streamly.Streaming.Streamly (StreamlyStream) import Frames.Streamly.ColumnTypeable () import qualified Data.Vinyl as V import qualified Data.Vinyl.Functor as V import qualified Text.Printf as Printf --import qualified Streamly.Prelude as Streamly import Data.Text (Text) -- for Frames template splicing import qualified Data.Text as Text import qualified Control.Foldl as FL import Data.List (intercalate) import DemoPaths (cesPath) FStreamly.tableTypes' Paths.ffBaseRowGen FStreamly.tableTypes' Paths.ffColSubsetRowGen FStreamly.tableTypes' Paths.ffColSubsetRowGenCat --FStreamly.tableTypes' Paths.cesRowGen FStreamly.tableTypes' Paths.ffInferOrMissingRG FStreamly.tableTypes' Paths.ffInferOrMissingCatRG FStreamly.tableTypes' Paths.ffInferTypedDayRG FStreamly.tableTypes' Paths.ffInferTypedDayOrMissingRG FStreamly.tableTypes' Paths.ffInferTypedDayMonthRG readTableOpt = FStreamly.readTableOpt @_ @FStreamly.DefaultStream main :: IO () main = do let rSafe = runSafe @FStreamly.DefaultStream forestFiresPath <- Paths.usePath Paths.forestFiresPath forestFires :: Frames.Frame ForestFires <- rSafe $ FStreamly.inCoreAoS $ FStreamly.readTableOpt @_ @FStreamly.DefaultStream @IO forestFiresParser forestFiresPath forestFiresColSubset :: Frames.Frame FFColSubset <- rSafe $ FStreamly.inCoreAoS $ readTableOpt fFColSubsetParser forestFiresPath let filterAndMap :: ForestFires -> Maybe (Frames.Record [FFX, FFY, FFMonth, FFDay, FFTemp, FFWind]) filterAndMap r = if Frames.rgetField @FFDay r == "fri" then (Just $ Frames.rcast r) else Nothing forestFires' = FStreamly.mapMaybe filterAndMap forestFires forestFiresColSubset' = FStreamly.filter (\r -> Frames.rgetField @FFDay r == "fri") forestFiresColSubset formatRow = FStreamly.formatWithShow V.:& FStreamly.formatWithShow V.:& FStreamly.formatTextAsIs V.:& FStreamly.formatTextAsIs V.:& FStreamly.liftFieldFormatter (Text.pack . Printf.printf "%.1f") V.:& FStreamly.liftFieldFormatter (Text.pack . Printf.printf "%.1f") V.:& V.RNil csvTextStream = FStreamly.streamSV' formatRow "," $ FStreamly.foldableToStream @_ @FStreamly.DefaultStream forestFires' -- csvTextStreamCS = FStreamly.streamSV' formatRow "," $ Streamly.fromFoldable forestFiresColSubset' -- putStrLn $ intercalate "\n" $ fmap show $ FL.fold FL.list forestFiresColSubset' -- Streamly.toList csvTextStream >>= putStrLn . Text.unpack . Text.intercalate "\n" FStreamly.writeLines "exampleOut.csv" csvTextStream -- FStreamly.writeLines "exampleOutCS.csv" csvTextStreamCS forestFiresMissingPath <- Paths.usePath Paths.forestFiresMissingPath -- try to load with ordinary row let tableLength :: Foldable f => f a -> Int tableLength = FL.fold FL.length forestFiresMissing :: Frames.Frame FFColSubset <- rSafe $ FStreamly.inCoreAoS $ readTableOpt fFColSubsetParser forestFiresMissingPath putStrLn $ "Loaded table with missing data using inferred row from complete table. Complete table has " <> show (tableLength forestFires) <> " and with missing data (1 row missing 'day' a Text entry, one missing 'wind', a Double) has " <> show (tableLength forestFiresMissing) forestFiresMissing2 :: Frames.Frame FFInferOrMissing <- rSafe $ FStreamly.inCoreAoS $ readTableOpt fFInferOrMissingParser forestFiresMissingPath putStrLn $ "Loaded the same table but with the types for 'day' and 'wind' set to OrMissing. Has " <> show (tableLength forestFiresMissing2) <> " rows." forestFiresTypedDay :: Frames.Frame FFInferTypedDay <- rSafe $ FStreamly.inCoreAoS $ readTableOpt fFInferTypedDayParser forestFiresMissingPath putStrLn $ "Loaded complete table with a DayOfWeek type added. Has " <> show (tableLength forestFiresTypedDay) <> " rows." forestFiresTypedDayOM :: Frames.Frame FFInferTypedDayOrMissing <- rSafe $ FStreamly.inCoreAoS $ readTableOpt fFInferTypedDayOrMissingParser forestFiresMissingPath putStrLn $ "Loaded table with missing data, a DayOfWeek type added and relevant columns set to OrMissing if some missing. Has " <> show (tableLength forestFiresTypedDayOM) <> " rows."