# Commander The commander package contains two DSLs for describing command line programs, one at the type level and one at the term level. The one at the type level looks like this: ```haskell type File = "writer" & Arg "file" FilePath & Arg "contents" FilePath Raw + "reader" & Arg "file" FilePath & Raw ``` This is a type which encodes information about an command line program we want to write. We can instantiate a term of this type by writing ```haskell file :: ProgramT File IO file = sub (arg \file -> arg \contents -> raw $ writeFile file contents) :+: sub (arg \file -> raw $ readFile file >>= putStrLn) ``` I can write a term of this type without specifying the File type by using the TypeApplications extension. ```haskell file = sub @"writer" (arg @"file" \file -> arg @"contents" \contents -> raw $ writeFile file contents) :+: sub @"reader" (arg @"file" \file -> raw $ readFile file >>= putStrLn) ``` The library consists of a few basic types which are important for understanding how to use it. The first thing is the class ```haskell class Unrender r where unrender :: Text -> Maybe r ``` This class is what you will use to define the parsing of a type from text and can use any parsing library or whatever you want. Next, we have the class ```haskell class HasProgram p where data ProgramT p m a run :: ProgramT p IO a -> CommanderT State IO a hoist :: (forall x. m x -> n x) -> ProgramT p m a -> ProgramT p n a invocations :: [Text] ``` Instances of this class will define a syntactic element, a new instance of the data family ProgramT, as well as its semantics in terms of the CommanderT monad, which is a backtracking monad based on a metaphor to military commanders which retreats upon defeat.