Skip to content

Instantly share code, notes, and snippets.

@ulysses4ever
Created August 26, 2015 08:23
Show Gist options
  • Save ulysses4ever/5b77ae93a0c0c2e40ce2 to your computer and use it in GitHub Desktop.
Save ulysses4ever/5b77ae93a0c0c2e40ce2 to your computer and use it in GitHub Desktop.
Parse indented text structure (algorithm thanks to http://stackoverflow.com/a/27217698/465100)
import Control.Applicative ((<$>))
data Cat = Cat String [Cat] deriving Show
indentLevel :: Int
indentLevel = 4 -- leading spaces
level :: String -> Int
level = (`div` indentLevel) . length . takeWhile (== ' ')
parse :: [String] -> [Cat]
parse [] = []
parse (x : xs) = Cat (trim x) (parse children) : parse sisters
where
(children, sisters) = span ((level x <) . level) xs
trim = dropWhile (== ' ')
parseStart :: String -> Cat
parseStart = head . parse . lines
main :: IO Cat
main = parseStart <$> readFile "example-indent.txt"
{-
example-indent.txt:
Cat 1
Cat 1.1
Cat 1.1.2
Cat 1.1.2
Cat 1.2
Cat 2
Cat 2.1
Cat 2.1.2
Cat 2.2
Cat 2.2.2
-}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment