项目作者: aslrousta

项目描述 :
Functional Pipeline in Go
高级语言: Go
项目地址: git://github.com/aslrousta/pipe.git
创建时间: 2019-12-18T23:47:09Z
项目社区:https://github.com/aslrousta/pipe

开源协议:MIT License

下载


Go Pipe

GitHub
GoDoc

Go Pipe is a simple implementation of pipe operator in Go.

What is it all about?

One of the most interesting features of functional languages is the ability to
easily compose functions. The function composition is the operation that takes
two functions and produces another function in the way that the result of the
second function is passed as the input argument of first one.

Function composition is so common in functional programming which most of the
functional languages have defined a special operator, typically called a pipe
operator, to make composition even simpler. For example, in Haskell we have the
. (dot) operator, and Elixir defines the |> (pipe) operator:

  1. append = fn list, item ->
  2. list
  3. |> Enum.reverse
  4. |> prepend.(item)
  5. |> Enum.reverse
  6. end

Actually, in any programming language which supports functional style we can
achieve the same result by applying functions consequently. For example in Go,
we can write:

  1. func h(x int) int {
  2. f := func(x int) int {
  3. if x < 0 {
  4. return -x
  5. } else {
  6. return x
  7. }
  8. }
  9. g := func(x int) int {
  10. return x * x
  11. }
  12. return f(g(x))
  13. }

But the problem arises when one of the func’s returns multiple values, as is
common with returning errors. In that case we need to handle error specifically
and write:

  1. func h(x int) (int, error) {
  2. f := func(x int) (int, error) {
  3. if x < 0 {
  4. return 0, errors.New("x should not be nagtive")
  5. }
  6. return x, nil
  7. }
  8. g := func(x int) int {
  9. return x * x
  10. }
  11. y, err := f(x)
  12. if err != nil {
  13. return 0, err
  14. }
  15. return g(y), nil
  16. }

This is not much complex for two func’s, but it can easily become a burden if
the number of func’s grows.

To overcome this complexity I’ve written this library to make life simpler for
those who love functional style like me. Go Pipe provides a Pipe func which
composes one or more funcs into a pipeline func, which can be invoked anytime
withing the code.

Using Pipe func is very simple:

  1. import . "github.com/aslrousta/pipe"
  2. func h(x int) int {
  3. var result int
  4. pipe := Pipe(
  5. func(x int) int {
  6. if x < 0 {
  7. return -x
  8. } else {
  9. return x
  10. }
  11. },
  12. func(x int) {
  13. result = x * x
  14. },
  15. )
  16. pipe(x)
  17. return result
  18. }

And, it can handle errors automatically:

  1. import . "github.com/aslrousta/pipe"
  2. func h(x int) (int, error) {
  3. var result int
  4. pipe := Pipe(
  5. func(x int) (int, error) {
  6. if x < 0 {
  7. return 0, errors.New("x should not be nagtive")
  8. }
  9. return x, nil
  10. },
  11. func(x int) {
  12. result = x * x
  13. },
  14. )
  15. err := pipe(x)
  16. return result, err
  17. }

License

Go Pipe source is released to the public under MIT license.