packages feed

hw-balancedparens-0.4.1.1: app/App/Commands/Positions.hs

{-# LANGUAGE DataKinds           #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}

module App.Commands.Positions
  ( cmdPositions
  ) where

import Control.Lens
import Control.Monad
import Data.Generics.Product.Any
import Data.Word
import HaskellWorks.Data.BalancedParens.FindClose
import HaskellWorks.Data.BalancedParens.OpenAt
import HaskellWorks.Data.Positioning
import Options.Applicative                        hiding (columns)

import qualified App.Commands.Options.Type           as Z
import qualified Data.Vector.Storable                as DVS
import qualified HaskellWorks.Data.FromForeignRegion as IO
import qualified System.IO                           as IO

{- HLINT ignore "Redundant do"        -}
{- HLINT ignore "Redundant return"    -}

openCloses :: (FindClose v, OpenAt v) => v -> [(Count, Count)]
openCloses v = go 1 v []
  where go :: (FindClose v, OpenAt v) => Count -> v -> [(Count, Count)] -> [(Count, Count)]
        go p w = if openAt w p
          then case findClose w p of
            Just q  -> ((p, q):) . go (p + 1) w . go (q + 1) w
            Nothing -> id
          else id

runPositions :: Z.PositionsOptions -> IO ()
runPositions opts = do
  let inputFile   = opts ^. the @"inputFile"

  v :: DVS.Vector Word64 <- IO.mmapFromForeignRegion inputFile

  forM_ (openCloses v) $ \(o, c) -> do
    IO.putStrLn $ show o <> "," <> show c

  return ()

optsPositions :: Parser Z.PositionsOptions
optsPositions = Z.PositionsOptions
  <$> strOption
      (   long "input"
      <>  help "Input file"
      <>  metavar "FILE"
      )

cmdPositions :: Mod CommandFields (IO ())
cmdPositions = command "positions"  $ flip info idm $ runPositions <$> optsPositions