# commander-cli
[](https://travis-ci.org/SamuelSchlesinger/commander-cli)
The commander-cli 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.