aboutsummaryrefslogtreecommitdiff
path: root/static
diff options
context:
space:
mode:
authorChristine Dodrill <me@christine.website>2020-05-23 12:04:53 -0400
committerGitHub <noreply@github.com>2020-05-23 12:04:53 -0400
commitdccacdd6ca25e36b88c52ee53dff34755e13169d (patch)
treec9cc1f8e75f649fa03043fa6f6e6819a75f3cc40 /static
parent21dee82c96bded64241ed9c2dcb1d3925868fa60 (diff)
downloadxesite-dccacdd6ca25e36b88c52ee53dff34755e13169d.tar.xz
xesite-dccacdd6ca25e36b88c52ee53dff34755e13169d.zip
blog: maybedoer (#153)
Diffstat (limited to 'static')
-rw-r--r--static/blog/maybedoer.go53
-rw-r--r--static/blog/maybedoer.pngbin0 -> 1056581 bytes
2 files changed, 53 insertions, 0 deletions
diff --git a/static/blog/maybedoer.go b/static/blog/maybedoer.go
new file mode 100644
index 0000000..4a69a12
--- /dev/null
+++ b/static/blog/maybedoer.go
@@ -0,0 +1,53 @@
+// Package maybedoer contains a pipeline of actions that might fail. If any action
+// in the chain fails, no further actions take place and the error becomes the pipeline
+// error.
+//
+// MIT License
+package maybedoer
+
+import "context"
+
+// Doer is a function that implements a fallible action that can be done.
+type Doer func(context.Context) error
+
+// Impl sequences a set of actions to be performed via calls to
+// `Maybe` such that any previous error prevents new actions from being
+// performed.
+//
+// This is, conceptually, just a go-ification of the Maybe monoid, but
+// defined to the error type in Go.
+type Impl struct {
+ Doers []Doer
+ err error
+}
+
+// Do executes the list of doers, right-folding the functions and seeing if one
+// returns an error. This is semantically identical to Data.Monoid.First in
+// Haskell, but specific to the error type in Go. Ideally this could be generalized
+// to any pointer-like datatype in Go, but Rob Pike says we can't have nice things.
+//
+// See the Haskell documentation for Data.Monad.First for more information:
+// http://hackage.haskell.org/package/base-4.14.0.0/docs/Data-Monoid.html#t:First
+func (c *Impl) Do(ctx context.Context) error {
+ for _, doer := range c.Doers {
+ c.Maybe(ctx, doer)
+ if c.err != nil {
+ return c.err
+ }
+ }
+
+ return nil
+}
+
+// Maybe performs `f` if no previous call to a Maybe'd action resulted
+// in an error
+func (c *Impl) Maybe(ctx context.Context, f func(ctx context.Context) error) {
+ if c.err == nil {
+ c.err = f(ctx)
+ }
+}
+
+// Error returns the first error encountered in the Error chain.
+func (c *Impl) Error() error {
+ return c.err
+}
diff --git a/static/blog/maybedoer.png b/static/blog/maybedoer.png
new file mode 100644
index 0000000..47234c6
--- /dev/null
+++ b/static/blog/maybedoer.png
Binary files differ