    module Hpack.Haskell (
      isModule
    , isQualifiedIdentifier
    , isIdentifier
    ) where

    import           Data.Char

    isModule :: [String] -> Bool
    isModule :: [String] -> Bool
    isModule name :: [String]
    name = (Bool -> Bool
    not (Bool -> Bool) -> ([String] -> Bool) -> [String] -> Bool
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [String] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null) [String]
    name Bool -> Bool -> Bool
    && (String -> Bool) -> [String] -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all String -> Bool
    isModuleName [String]
    name

    isModuleName :: String -> Bool
    isModuleName :: String -> Bool
    isModuleName name :: String
    name = case String
    name of
      x :: Char
    x : xs :: String
    xs -> Char -> Bool
    isUpper Char
    x Bool -> Bool -> Bool
    && (Char -> Bool) -> String -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all Char -> Bool
    isIdChar String
    xs
      _ -> Bool
    False

    isQualifiedIdentifier :: [String] -> Bool
    isQualifiedIdentifier :: [String] -> Bool
    isQualifiedIdentifier name :: [String]
    name = case [String] -> [String]
    forall a. [a] -> [a]
    reverse [String]
    name of
      x :: String
    x : xs :: [String]
    xs  -> String -> Bool
    isIdentifier String
    x Bool -> Bool -> Bool
    && [String] -> Bool
    isModule [String]
    xs
      _ -> Bool
    False

    isIdentifier :: String -> Bool
    isIdentifier :: String -> Bool
    isIdentifier name :: String
    name = case String
    name of
      x :: Char
    x : xs :: String
    xs -> Char -> Bool
    isLower Char
    x Bool -> Bool -> Bool
    && (Char -> Bool) -> String -> Bool
    forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
    all Char -> Bool
    isIdChar String
    xs Bool -> Bool -> Bool
    && String
    name String -> [String] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    `notElem` [String]
    reserved
      _ -> Bool
    False

    reserved :: [String]
    reserved :: [String]
    reserved = [
        "case"
      , "class"
      , "data"
      , "default"
      , "deriving"
      , "do"
      , "else"
      , "foreign"
      , "if"
      , "import"
      , "in"
      , "infix"
      , "infixl"
      , "infixr"
      , "instance"
      , "let"
      , "module"
      , "newtype"
      , "of"
      , "then"
      , "type"
      , "where"
      , "_"
      ]

    isIdChar :: Char -> Bool
    isIdChar :: Char -> Bool
    isIdChar c :: Char
    c = Char -> Bool
    isAlphaNum Char
    c Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == '_' Bool -> Bool -> Bool
    || Char
    c Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == '\''