Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@erthink
Created February 25, 2020 22:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erthink/b7936acf3c397064c0b5d2852532bd50 to your computer and use it in GitHub Desktop.
Save erthink/b7936acf3c397064c0b5d2852532bd50 to your computer and use it in GitHub Desktop.
Simple ASCII-only version of wc util
{-# LANGUAGE Strict #-}
{-# LANGUAGE RecordWildCards #-}
import qualified Data.ByteString as BS
import System.Environment
import System.IO.Posix.MMap
data State = State
{ bs :: Int
, ws :: Int
, ls :: Int
, wasSpace :: Int
}
wc :: BS.ByteString -> (Int, Int, Int)
wc s = (bs, ws + 1 - wasSpace, ls)
where
State { .. } = BS.foldl' go (State 0 0 0 1) s
go State { .. } c = State (bs + 1) (ws + addWord) (ls + addLine) isSp
where
isSp | c == 32 || c - 9 <= 4 = 1
| otherwise = 0
addLine | c == 10 = 1
| otherwise = 0
addWord = (1 - wasSpace) * isSp
{-# INLINE wc #-}
main :: IO ()
main = do
[path] <- getArgs
contents <- unsafeMMapFile path
print $ wc contents
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment