Skip to content
Permalink
Browse files

Changed `Err{}` to be a function instead. (#360)

The underlying type is now gErr. It implements Result and error.
  • Loading branch information
chewxy committed Jan 5, 2020
1 parent dc9e605 commit b31926728312463c7f5e729e4a8fcc2b1c75182c
Showing with 26 additions and 16 deletions.
  1. +26 −16 ermagerdmonards.go
@@ -7,7 +7,7 @@ import (
var (
_ Result = (*Node)(nil)
_ Result = (Nodes)(nil)
_ Result = Err{}
_ Result = gErr{}
)

// Result is either a Node or Nodes or error. It's a poor man's sum types and it's not sealed for good reason
@@ -32,7 +32,7 @@ type Errer interface {
func Lift1(fn func(a *Node) (*Node, error)) func(a Input) Result {
return func(a Input) Result {
if err := CheckOne(a); err != nil {
return Err{errors.WithStack(err)}
return Err(errors.WithStack(err))
}
return LiftResult(fn(a.Node()))
}
@@ -42,7 +42,7 @@ func Lift1(fn func(a *Node) (*Node, error)) func(a Input) Result {
func Lift1Axial(fn func(a *Node, axes ...int) (*Node, error)) func(a Input, axes ...int) Result {
return func(a Input, axes ...int) Result {
if err := CheckOne(a); err != nil {
return Err{errors.WithStack(err)}
return Err(errors.WithStack(err))
}
return LiftResult(fn(a.Node(), axes...))
}
@@ -52,10 +52,10 @@ func Lift1Axial(fn func(a *Node, axes ...int) (*Node, error)) func(a Input, axes
func Lift2(fn func(a, b *Node) (*Node, error)) func(a, b Input) Result {
return func(a, b Input) Result {
if err := CheckOne(a); err != nil {
return Err{errors.WithStack(err)}
return Err(errors.WithStack(err))
}
if err := CheckOne(b); err != nil {
return Err{errors.WithStack(err)}
return Err(errors.WithStack(err))
}
return LiftResult(fn(a.Node(), b.Node()))
}
@@ -65,30 +65,40 @@ func Lift2(fn func(a, b *Node) (*Node, error)) func(a, b Input) Result {
func Lift2Broadcast(fn func(a, b *Node, pat1, pat2 []byte) (*Node, error)) func(a, b Input, pat1, pat2 []byte) Result {
return func(a, b Input, pat1, pat2 []byte) Result {
if err := CheckOne(a); err != nil {
return Err{errors.WithStack(err)}
return Err(errors.WithStack(err))
}
if err := CheckOne(b); err != nil {
return Err{errors.WithStack(err)}
return Err(errors.WithStack(err))
}
return LiftResult(fn(a.Node(), b.Node(), pat1, pat2))
}
}

// Err implements Result
type Err struct{ E error }
// gErr implements Result and error.
type gErr struct{ error }

func (err Err) Node() *Node { return nil }
func (err Err) Nodes() Nodes { return nil }
func (err Err) Err() error { return err.E }
// Err is a function that returns a gErr. It wraps errors with stack information.
// A gErr implements Result, as well as error.
// This way, the Err() method acts as an unwrapper.
func Err(e error) gErr { return gErr{errors.WithStack(e)} }

func (err gErr) Node() *Node { return nil }
func (err gErr) Nodes() Nodes { return nil }
func (err gErr) Err() error { return err.error }

// resultM is a wrapper for Input to create a Result. This is the default Result if an unknown Input was passed in.
type resultM struct{ Input }

func (r resultM) Err() error { return nil }

// LiftResult creates a Result from a Input and error pair.
// If the error is not nil, the Input is discarded.
//
// The usual use case is in a function that returns a `(*Node, error)`.
// e.g LiftResult(Add(a, b))
func LiftResult(a Input, err error) Result {
if err != nil {
return Err{err}
return Err(err)
}
switch at := a.(type) {
case Result:
@@ -109,8 +119,8 @@ func CheckOne(in Input) error {
// NodesFromInputs creates a Nodes from a list of Input.
func NodesFromInputs(xs ...Input) (Nodes, error) {
for i := range xs {
if err:= CheckOne(xs[i]); err != nil{
return nil, errors.Wrapf(err, "NodesFromInputs %dth input",i)
if err := CheckOne(xs[i]); err != nil {
return nil, errors.Wrapf(err, "NodesFromInputs %dth input", i)
}
// check if the Input is a *Node
if xs[i].Node() == nil {
@@ -119,7 +129,7 @@ func NodesFromInputs(xs ...Input) (Nodes, error) {
}

retVal := make(Nodes, len(xs))
for i :=range xs {
for i := range xs {
retVal[i] = xs[i].Node()
}
return retVal, nil

0 comments on commit b319267

Please sign in to comment.
You can’t perform that action at this time.