raft-0.3.2.2: src/Data/List/Util/Listable.hs
-----------------------------------------------------------------------------
--
-- Module : Data.List.Util.Listable
-- Copyright : (c) 2014-16 Brian W Bush
-- License : MIT
--
-- Maintainer : Brian W Bush <consult@brianwbush.info>
-- Stability : Experimental
-- Portability : Portable
--
-- | For CSV-like and TSV-like data.
--
-----------------------------------------------------------------------------
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE Safe #-}
module Data.List.Util.Listable (
-- * Tabbed Strings
tab
, fromTabbed
, toTabbed
, fromTabbeds
, toTabbeds
-- * Converting to/from Lists
, Listable(..)
, fromStringList
, toStringList
, fromTabbedList
, toTabbedList
, fromStringLists
, toStringLists
, fromTabbedLists
, toTabbedLists
, fromTransposedTabbedLists
, toTransposedTabbedLists
-- * Dealing with Headers
, WithHeader(..)
, fromStringListsWithHeader
, toStringListsWithHeader
, fromTabbedListsWithHeader
, toTabbedListsWithHeader
, readTabbedListsWithHeader
, writeTabbedListsWithHeader
, fromTransposedTabbedListsWithHeader
, toTransposedTabbedListsWithHeader
, readTransposedTabbedListsWithHeader
, writeTransposedTabbedListsWithHeader
) where
import Control.Applicative (liftA2)
import Control.Arrow ((&&&))
import Data.List (intercalate, transpose)
import Data.List.Split (splitOn)
import Data.String.Util (Stringy(..))
-- | Tab character.
tab :: String
tab = "\t"
-- | Separate a tabbed string.
fromTabbed :: String -- ^ The tabbed strings.
-> [String] -- ^ The strings between the tabs.
fromTabbed = splitOn tab
-- | Intercalate tabs between strings.
toTabbed :: [String] -- ^ The strings.
-> String -- ^ The intercalated string.
toTabbed = intercalate tab
-- | Separate lines and tabs.
fromTabbeds :: String -- ^ The string.
-> [[String]] -- ^ The lines and strings between tabs.
fromTabbeds = fmap fromTabbed . lines
-- | Intercalte lines and tabs.
toTabbeds :: [[String]] -- ^ The lines and strings between tabs.
-> String -- ^ The intercalated string.
toTabbeds = unlines . fmap toTabbed
-- | Class for conversion to/from lists.
class Listable a b | a -> b where
-- | Convert from a list.
fromList :: [b] -- ^ The list of values.
-> a -- ^ The combined value.
-- | Convert to a list.
toList :: a -- ^ The value.
-> [b] -- ^ THe list of values.
-- | Convert from a list of strings.
fromStringList :: (Listable a b, Stringy b)
=> [String] -- ^ The strings.
-> a -- ^ The value.
fromStringList = fromList . fmap fromString
-- | Convert to a list of strings.
toStringList :: (Listable a b, Stringy b)
=> a -- ^ The value.
-> [String] -- ^ The strings.
toStringList = fmap toString . toList
-- | Convert from a tabbed lines.
fromTabbedList :: (Listable a b, Stringy b)
=> String -- ^ The tabbed list.
-> a -- ^ The value.
fromTabbedList = fromStringList . fromTabbed
-- | Convert to a tabbed lines.
toTabbedList :: (Listable a b, Stringy b)
=> a -- ^ The value.
-> String -- ^ The tabbed string.
toTabbedList = toTabbed . toStringList
-- | Convert from a list of strings.
fromStringLists :: (Listable a b, Listable b c, Stringy c)
=> [[String]] -- ^ The lists of strings.
-> a -- ^ The value.
fromStringLists = fromList . fmap fromStringList
-- | Convert to a list of strings.
toStringLists :: (Listable a b, Listable b c, Stringy c)
=> a -- ^ The value.
-> [[String]] -- ^ The lists of strings.
toStringLists = fmap toStringList . toList
-- | Convert from tabbed lines.
fromTabbedLists :: (Listable a b, Listable b c, Stringy c)
=> String -- ^ The tabbed lines.
-> a -- ^ The value.
fromTabbedLists = fromStringLists . fromTabbeds
-- | Convert to tabbed lines.
toTabbedLists :: (Listable a b, Listable b c, Stringy c)
=> a -- ^ The value.
-> String -- ^ The tabbed lines.
toTabbedLists = toTabbeds . toStringLists
-- | Convert from transposed tabbed lines.
fromTransposedTabbedLists :: (Listable a b, Listable b c, Stringy c)
=> String -- ^ The tranposed tabbed lines.
-> a -- ^ The value.
fromTransposedTabbedLists = fromStringLists . transpose . fromTabbeds
-- | Convert to transposed tabbed lines.
toTransposedTabbedLists :: (Listable a b, Listable b c, Stringy c)
=> a -- ^ The value.
-> String -- ^ The transposed tabbed lines.
toTransposedTabbedLists = toTabbeds . transpose . toStringLists
-- | Class for lists of strings with a headers.
class WithHeader a b | a -> b where
-- | Convert from a list of values with headers.
fromHeaderLists :: ([String], [b]) -- ^ The headers and values.
-> a -- ^ The combined value.
-- | Convert to a list of values with headers.
toHeaderLists :: a -- ^ The combined value.
-> ([String], [b]) -- ^ The headers and values.
-- | Convert from lists of strings with a header.
fromStringListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> [[String]] -- ^ The lists of strings.
-> a -- ^ The value.
fromStringListsWithHeader = fromHeaderLists . (head &&& fmap fromStringList . tail)
-- | Convert to lists of strings with a header.
toStringListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> a -- ^ The value.
-> [[String]] -- ^ The lists of strings.
toStringListsWithHeader = liftA2 (:) fst (fmap toStringList . snd) . toHeaderLists
-- | Convert from lines with a header.
fromTabbedListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> String -- ^ The lines.
-> a -- ^ The value.
fromTabbedListsWithHeader = fromStringListsWithHeader . fromTabbeds
-- | Convert to lines with a header.
toTabbedListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> a -- ^ The value.
-> String -- ^ The lines.
toTabbedListsWithHeader = toTabbeds . toStringListsWithHeader
-- | Read lines with a header.
readTabbedListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> FilePath -- ^ The file.
-> IO a -- ^ Action for reading the value.
readTabbedListsWithHeader = fmap fromTabbedListsWithHeader . readFile
-- | Write lines with a header.
writeTabbedListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> FilePath -- ^ The file path.
-> a -- ^ The value.
-> IO () -- ^ The action for writing the value.
writeTabbedListsWithHeader = (. toTabbedListsWithHeader) . writeFile
-- | Convert from tabbed lines with a header.
fromTransposedTabbedListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> String -- ^ The tabbed lines.
-> a -- ^ The value.
fromTransposedTabbedListsWithHeader = fromStringListsWithHeader . transpose . fromTabbeds
-- | Convert to tabbed lines with a header.
toTransposedTabbedListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> a -- ^ The value.
-> String -- ^ The tabbed lines.
toTransposedTabbedListsWithHeader = toTabbeds . transpose . toStringListsWithHeader
-- | Read tabbed lines with a header.
readTransposedTabbedListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> FilePath -- ^ The file path.
-> IO a -- ^ Action for reading the value.
readTransposedTabbedListsWithHeader = fmap fromTransposedTabbedListsWithHeader . readFile
-- | Write tabbed lines with a header.
writeTransposedTabbedListsWithHeader :: (WithHeader a b, Listable b c, Stringy c)
=> FilePath -- ^ The file path.
-> a -- ^ The value.
-> IO () -- ^ The action for writing the value.
writeTransposedTabbedListsWithHeader = (. toTransposedTabbedListsWithHeader) . writeFile