parse :: FilePath -> IO (Maybe [Rule])
parse path = do 
    strs <- zip [1..] . map stripComments . lines <$> readFile path
    x <- mapM parseRule $ filter (not . null) $ splitWhen (all isSpace . snd) strs
    return $ if not (any (any isNothing) x) then Just $ concatMap catMaybes x
                                            else Nothing
  where stripComments = takeWhile (/= '#')
parse :: FilePath -> IO (Maybe [Rule])
parse path = do 
    strs <- zip [1..] . map stripComments . lines <$> readFile path
    x <- mapM parseRule $ filter (not . null) $ splitWhen (all isSpace . snd) strs
    return $ if not (any (any isNothing) x) then Just $ concatMap catMaybes x
                                            else Nothing
  where stripComments = takeWhile (/= '#')
parse path = do 
    strs <- zip [1..] . map stripComments . lines <$> readFile path
    x <- mapM parseRule $ filter (not . null) $ splitWhen (all isSpace . snd) strs
    return $ if not (any (any isNothing) x) then Just $ concatMap catMaybes x
                                            else Nothing
  where stripComments = takeWhile (/= '#')