-- | -- Module : Data.Lists.FLines -- Copyright : (c) OleksandrZhabenko 2020 -- License : MIT -- Stability : Experimental -- Maintainer : olexandr543@yahoo.com -- -- Additional data and structures to some 'String'-related lists. -- {-# LANGUAGE CPP, FlexibleInstances, MultiParamTypeClasses #-} module Data.Lists.FLines where #ifdef __GLASGOW_HASKELL__ #if __GLASGOW_HASKELL__>=710 /* code that applies only to GHC 7.10.* and higher versions */ import GHC.Base (mconcat) #endif #endif import System.IO #ifdef __GLASGOW_HASKELL__ #if __GLASGOW_HASKELL__==708 /* code that applies only to GHC 7.8.* */ mconcat = concat #endif #endif -- | Auxiliary printing function to define the line ending needed to be shown and printed. Is primarily defined in the @uniqueness-periods-vector-general@ package (https://hackage.haskell.org/package/uniqueness-periods-vector-general). newLineEnding :: String newLineEnding | nativeNewline == LF = "\n" | otherwise = "\r\n" data FLines a = F1 a | FL [a] deriving Eq type Flines = FLines String -- | Is intended to be printed and so adds the new line ending. instance Show (FLines String) where show (F1 xs) = mconcat [xs, newLineEnding] show (FL (xs:xss)) = mconcat (xs:newLineEnding:[show (FL xss)]) show _ = newLineEnding class GetN a b where getN :: Int -> a -> Maybe b instance GetN (FLines String) String where getN n (F1 xs) | null xs = Nothing | n == 1 = Just xs | otherwise = Nothing getN n (FL (xs:xss)) | n == 1 = if null xs then Nothing else Just xs | compare n 1 == LT = Nothing | otherwise = getN (n - 1) (FL xss) getN _ _ = Nothing class GetNTrans a b where getNT :: Int -> (b -> b) -> a -> Maybe b instance GetNTrans (FLines String) String where getNT n g (F1 xs) | null (g xs) = Nothing | n == 1 = Just (g xs) | otherwise = Nothing getNT n g (FL (xs:xss)) | n == 1 = if null (g xs) then Nothing else Just (g xs) | compare n 1 == LT = Nothing | otherwise = getNT (n - 1) g (FL xss) getNT _ _ _ = Nothing