# 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.