Skip to content

SimonRichardson/pipes

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

33 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pipes

Commands

Monadic commands

A very simple, but powerful monadic command runner, where commands declare functions to be run.

Since the Go language lacks defining total immutable state, it's thought of as best practice. If using the command runner the commands are created once, so any state created in there could effect the next run, so be very careful.

Examples

The example is a lot more up to date by it's very nature of being code, but to give you an idea, see the following:

Create a set of commands that we want to use:

type AddCommand struct {
    x Int
}

func NewAddCommand() AddCommand {
    return AddCommand{
        x: NewInt(1),
    }
}

func (c AddCommand) Execute(note pipes.Note) pipes.CommandResult {
    return pipes.ContinueResult(note.(Conf).Map(func(x Val) Val {
        return NewVal(x.Sum().Run(c.x).(Int))
    }))
}

Create a successful program:

conf := NewConf(NewVal(NewInt(0)))

program := pipes.EitherT{}.Of(conf).
    Eff(pipes.Do(NewAddCommand())).
    Eff(pipes.Do(NewAddCommand())).
    Eff(pipes.Do(NewAddCommand()))
program.Run.Run()
// (Right (3), [Right (0) Right (1) Right (2)])

For a unsuccessful program:

conf := NewConf(NewVal(NewInt(0)))

program := pipes.EitherT{}.Of(conf).
    Eff(pipes.Do(NewAddCommand())).
    Eff(pipes.Do(NewBadCommand())).
    Eff(pipes.Do(NewAddCommand()))
program.Run.Run()
// (Left (1), [Right (0) Right (1) Left (1)])

Notes

Although some of the structs are named after other functional language types (Either, etc), they are not in fact the same. They're close, but each type has been locked down to a tighter set of types, to prevent the need for type casting. Which means they'll not pass any monadic laws!!

About

Monadic Commands

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages