Skip to content

Instantly share code, notes, and snippets.

@erikkaplun
Created November 23, 2019 15:21
Show Gist options
  • Save erikkaplun/bc38e3f61cfe9f511aab0d40569fe0c4 to your computer and use it in GitHub Desktop.
Save erikkaplun/bc38e3f61cfe9f511aab0d40569fe0c4 to your computer and use it in GitHub Desktop.
import Char (isAlpha)
import List (intercalate)
type Name = [NameChar]
type NameChar = Char
nameChar2char :: Char -> NameChar
nameChar2char c | isAlpha c = c
name2str :: Name -> String
name2str = map nameChar2char
data Node = Node { nodeName :: Name
, attrs :: [Attr]
, children :: [Node] }
data Attr = Attr { attrName :: Name
, value :: String }
attr2string :: Attr -> String
attr2string (Attr name value) =
name2str name ++ "=\"" ++ escape value ++ "\""
where escape = concatMap (\c -> if c == '"' then "\\\"" else [c])
node2string :: Node -> String
node2string (Node name attrs children)
| null children = "<" ++ name' ++ attrs' ++ "/>"
| otherwise = "<" ++ name' ++ attrs' ++ ">" ++ children' ++ "</" ++ name' ++ ">"
where name' = name2str name
attrs' = (concatMap ((" " ++) . attr2string) attrs)
children' = intercalate "" $ map (node2string) children
inverse :: (a -> b) -> (b -> a)
inverse f y | f x =:= y = x where x free
parse :: String -> Node
parse = inverse node2string
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment