strym

module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 21, 2022 License: MIT

README

strym

Strym is a lazy stream library for Go.

  • Go 1.18+ Generics
  • Lazy Stream
  • with Error Stream

Install

go get github.com/shunkeen/strym
go mod tidy

Usage

package main

import (
	"fmt"
	"strconv"

	"github.com/shunkeen/strym/lazy"
)

func main() {
	xs := []string{"2", "a", "3", "b"}

	y, _ := lazy.Run4(
		lazy.FromSlice(xs),
		lazy.TryMap(strconv.Atoi),
		lazy.IgnoreErr[int](),
		lazy.Sum(),
	)

	fmt.Println(y) // 5
}

Spec

  • Producer
    • FromSlice
    • Iterate
    • Repeat
    • CycleSlice
    • Replicate
    • Flatten
    • FlatMap
    • Range
    • RangeTo
    • RangeBy
    • ZipWith
    • ZipWith3
    • Zip
    • Zip3
    • Once
    • ThrowOnce
  • Prosumer
    • Map
    • TryMap
    • Filter
    • TryFilter
    • IgnoreErr
    • Reverse
    • Take
    • Drop
    • TakeWhile
    • DropWhile
    • BreakIfErr
    • Concat
    • ConcatMap
    • Scan
    • Scan1
  • Consumer
    • ToSlice
    • Redirect
    • First
    • Last
    • Nth
    • Includes
    • Max
    • Min
    • Sum
    • Product
    • IsEmpty
    • Count
    • And
    • Or
    • All
    • Any
    • ForEach
    • Reduce
    • Reduce1
    • SparkWith
    • Spark
  • Other
    • Run1 -- Run12
    • Chain2 -- Chain10
    • ChainHM
    • ChainPD
    • ChainCS

Examples

Producer
FromSlice
// import "github.com/shunkeen/strym/lazy"
xs, _ := lazy.Run2(
    lazy.FromSlice([]int{0, 1, 2, 3, 4}),
    lazy.ToSlice[int](),
)
// []int{0, 1, 2, 3, 4}
Iterate
xs, _ := lazy.Run3(
    lazy.Iterate(true, func(x bool) bool { return !x }),
    lazy.Take[bool](5),
    lazy.ToSlice[bool](),
)
// []bool{true, false, true, false, true}
Repeat
xs, _ := lazy.Run3(
    lazy.Repeat(17),
    lazy.Take[int](5),
    lazy.ToSlice[int](),
)
// []int{17, 17, 17, 17, 17}
Repeat
xs, _ := lazy.Run3(
    lazy.CycleSlice([]int{2, 5, 7}),
    lazy.Take[int](5),
    lazy.ToSlice[int](),
)
// []int{2, 5, 7, 2, 5}
Replicate
xs, _ := lazy.Run2(
    lazy.Replicate(4, true),
    lazy.ToSlice[bool](),
)
// []bool{true, true, true, true}
Flatten
xs, _ := lazy.Run2(
    lazy.Flatten(lazy.ChainPD(
        lazy.FromSlice([]int{0, 1, 2, 3}),
        lazy.Map(lazy.Range),
    )),
    lazy.ToSlice[int](),
)
// []int{0, 0, 1, 0, 1, 2}
FlatMap
xs, _ := lazy.Run2(
    lazy.FlatMap(
        lazy.FromSlice([]int{0, 1, 2, 3}),
        lazy.Range,
    ),
    lazy.ToSlice[int](),
)
// []int{0, 0, 1, 0, 1, 2}
Range
xs, _ := lazy.Run2(
    lazy.Range(5),
    lazy.ToSlice[int](),
)
// []int{0, 1, 2, 3, 4}

ys, _ := lazy.Run2(
    lazy.RangeTo(5, 10),
    lazy.ToSlice[int](),
)
// []int{5, 6, 7, 8, 9}

zs, _ := lazy.Run2(
    lazy.RangeBy(0, 10, 2),
    lazy.ToSlice[int](),
)
// []int{0, 2, 4, 6, 8}
xs, _ := lazy.Run2(
    lazy.RangeBy(8, 0, -2),
    lazy.ToSlice[int](),
)
// []int{8, 6, 4, 2}

ys, _ := lazy.Run2(
    lazy.RangeInteger[int64](5),
    lazy.ToSlice[int64](),
)
// []int64{0, 1, 2, 3, 4}

zs, _ := lazy.Run2(
    lazy.RangeFloatBy(1.0, 0.5, -0.1),
    lazy.ToSlice[float64](),
)
// []float64{1.0, 0.9, 0.8, 0.7, 0.6}
ZipWith
xs, _ := lazy.Run2(
    lazy.ZipWith(
        lazy.FromSlice([]int{1, 2, 3}),
        lazy.FromSlice([]int{4, 5, 6}),
        func(x, y int) int { return x + y },
    ),
    lazy.ToSlice[int](),
)
// []int{5, 7, 9}

ys, _ := lazy.Run2(
    lazy.ZipWith3(
        lazy.FromSlice([]int{7, 8, 9}),
        lazy.FromSlice([]int{4, 5, 6}),
        lazy.FromSlice([]int{1, 2, 3}),
        func(x, y, z int) int { return x - y - z },
    ),
    lazy.ToSlice[int](),
)
// []int{2, 1, 0}
Zip
// import "github.com/shunkeen/eager/datatype/tuple"
xs, _ := lazy.Run2(
    lazy.Zip(
        lazy.FromSlice([]int{1, 2}),
        lazy.FromSlice([]string{"A", "B"}),
    ),
    lazy.ToSlice[tuple.Tuple2[int, string]](),
)
x1, x2 := xs[0]()
// 1, "A"

x1, x2 = xs[1]()
// 2, "B"

ys, _ := lazy.Run2(
    lazy.Zip3(
        lazy.FromSlice([]int{1, 2}),
        lazy.FromSlice([]string{"A", "B"}),
        lazy.FromSlice([]bool{true, false}),
    ),
    lazy.ToSlice[tuple.Tuple3[int, string, bool]](),
)
x1, x2, x3 := ys[0]()
// 1, "A", true

x1, x2, x3 = ys[1]()
// 2, "B", false
Once
xs, _ := lazy.Run2(
    lazy.Once(999),
    lazy.ToSlice[int](),
)
// []int{999}
OnceThrow
// import "errors"
_, err := lazy.Run2(
    lazy.ThrowOnce[int](errors.New("once")),
    lazy.ToSlice[int](),
)
// *errors.errorString {s: "once"}
Prosumer
Map
xs, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3}),
    lazy.Map(func(x int) int { return x + 1 }),
    lazy.ToSlice[int](),
)
// []int{2, 3, 4}
TryMap
// import "strconv"
// import "github.com/shunkeen/eager/datatype/tuple"
tuple2, _ := lazy.Run3(
    lazy.FromSlice([]string{"1", "a", "2"}),
    lazy.TryMap(strconv.Atoi),
    lazy.Redirect(
        lazy.ToSlice[int](),
        lazy.ToSlice[error](),
    ),
)
xs, es := tuple2()
// []int{1, 2}, []error{*errors.errorString {s: "invalid syntax"}}
Filter
xs, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3}),
    lazy.Filter(func(x int) bool { return (x % 2) != 0 }),
    lazy.ToSlice[int](),
)
// []int{1, 3}
TryFilter
// import "errors"
// import "github.com/shunkeen/eager/datatype/tuple"
f := func(x int) error {
    if (x % 2) == 0 {
        return errors.New("even")
    }
    return nil
}

tuple2, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3}),
    lazy.TryFilter(f),
    lazy.Redirect(
        lazy.ToSlice[int](),
        lazy.ToSlice[error](),
    ),
)
xs, es := tuple2()
// []int{1, 3}, []error{*errors.errorString {s: "even"}}
IgnoreErr
// import "strconv"
xs, _ := lazy.Run4(
    lazy.FromSlice([]string{"1", "a", "2"}),
    lazy.TryMap(strconv.Atoi),
    lazy.IgnoreErr[int](),
    lazy.ToSlice[int](),
)
// []int{1, 2}
Reverse
xs, _ := lazy.Run3(
    lazy.FromSlice([]int{2, 5, 7}),
    lazy.Reverse[int](),
    lazy.ToSlice[int](),
)
// []int{7, 5, 2}
Take
xs, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3, 4, 5}),
    lazy.Take[int](3),
    lazy.ToSlice[int](),
)
// []int{1, 2, 3}
Drop
xs, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3, 4, 5}),
    lazy.Drop[int](3),
    lazy.ToSlice[int](),
)
// []int{4, 5}
TakeWhile
xs, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3, 4, 1, 2, 3, 4}),
    lazy.TakeWhile(func(x int) bool { return x < 3 }),
    lazy.ToSlice[int](),
)
// []int{1, 2}
TakeWhile
xs, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3, 4, 5, 1, 2, 3}),
    lazy.DropWhile(func(x int) bool { return x < 3 }),
    lazy.ToSlice[int](),
)
// []int{3, 4, 5, 1, 2, 3}
BreakIfErr
// import "strconv"
xs, _ := lazy.Run4(
    lazy.FromSlice([]string{"1", "a", "2"}),
    lazy.TryMap(strconv.Atoi),
    lazy.BreakIfErr[int](),
    lazy.ToSlice[int](),
)
// []int{1}
Concat
xs, _ := lazy.Run4(
    lazy.FromSlice([][]int{{1, 2, 3}, {4, 5}, {6}, {}}),
    lazy.Map(lazy.FromSlice[int]),
    lazy.Concat[int](),
    lazy.ToSlice[int](),
)
// []int{1, 2, 3, 4, 5, 6}
ConcatMap
xs, _ := lazy.Run3(
    lazy.Range(4),
    lazy.ConcatMap(lazy.Range),
    lazy.ToSlice[int](),
)
// []int{0, 0, 1, 0, 1, 2}
Scan
xs, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3, 4}),
    lazy.Scan(0, func(x, y int) int { return x + y }),
    lazy.ToSlice[int](),
)
// []int{0, 1, 3, 6, 10}
Scan1
xs, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3, 4}),
    lazy.Scan1(func(x, y int) int { return x + y }),
    lazy.ToSlice[int](),
)
// []int{1, 3, 6, 10}

Consumer
ToSlice
xs, _ := lazy.Run2(
    lazy.FromSlice([]int{0, 1, 2, 3, 4}),
    lazy.ToSlice[int](),
)
// []int{0, 1, 2, 3, 4}
Redirect
// import "strconv"
// import "github.com/shunkeen/eager/datatype/tuple"
tuple2, _ := lazy.Run3(
    lazy.FromSlice([]string{"1", "a", "2"}),
    lazy.TryMap(strconv.Atoi),
    lazy.Redirect(
        lazy.ToSlice[int](),
        lazy.ToSlice[error](),
    ),
)
xs, es := tuple2()
// []int{1, 2}, []error{*errors.errorString {s: "invalid syntax"}}
First
x, _ := lazy.Run2(
    lazy.FromSlice([]int{1, 2, 3}),
    lazy.First[int](),
)
// 1
Last
x, _ := lazy.Run2(
    lazy.FromSlice([]int{1, 2, 3}),
    lazy.Last[int](),
)
// 3
Nth
x, _ := lazy.Run2(
    lazy.FromSlice([]int{1, 2, 3}),
    lazy.Nth[int](1),
)
// 2
Includes
x, _ := lazy.Run2(
    lazy.FromSlice([]int{1, 2, 3, 4, 5}),
    lazy.Includes(3),
)
// true
Max
x, _ := lazy.Run2(
    lazy.FromSlice([]int{3, 4, 2, 0, 1}),
    lazy.Max[int](),
)
// 4
Min
x, _ := lazy.Run2(
    lazy.FromSlice([]int{3, 4, 2, 0, 1}),
    lazy.Min[int](),
)
// 0
Sum
x, _ := lazy.Run2(
    lazy.FromSlice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}),
    lazy.Sum(),
)
// int(55)

y, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}),
    lazy.Map(func(x int) int64 { return int64(x) }),
    lazy.SumInteger[int64](),
)
// int64(55)

z, _ := lazy.Run2(
    lazy.FromSlice([]float64{4.1, 2.0, 1.7}),
    lazy.SumFloat[float64](),
)
// float64(7.8)
Product
x, _ := lazy.Run2(
    lazy.FromSlice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}),
    lazy.Product(),
)
// int(3628800)

y, _ := lazy.Run3(
    lazy.FromSlice([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}),
    lazy.Map(func(x int) int64 { return int64(x) }),
    lazy.ProductInteger[int64](),
)
// int64(3628800)

z, _ := lazy.Run2(
    lazy.FromSlice([]float64{4.1, 2.0, 1.7}),
    lazy.ProductFloat[float64](),
)
// float64(13.939999999999998)
IsEmpty
x, _ := lazy.Run2(lazy.FromSlice([]int{}), lazy.IsEmpty[int]())
// true

y, _ := lazy.Run2(lazy.FromSlice([]int{1}), lazy.IsEmpty[int]())
// false
Count
x, _ := lazy.Run2(
    lazy.FromSlice([]string{"a", "b", "c"}),
    lazy.Count[string](),
)
// 3
And
x, _ := lazy.Run2(
    lazy.FromSlice([]bool{true, false, true}),
    lazy.And(),
)
// false
Or
x, _ := lazy.Run2(
    lazy.FromSlice([]bool{true, false, true}),
    lazy.Or(),
)
// true
All
x, _ := lazy.Run2(
    lazy.FromSlice([]int{3, 1, 4}),
    lazy.All(func(x int) bool { return x > 2 }),
)
// false
Any
x, _ := lazy.Run2(
    lazy.FromSlice([]int{3, 1, 4}),
    lazy.Any(func(x int) bool { return x > 2 }),
)
// true
ForEach
var acc string
lazy.Run2(
    lazy.FromSlice([]string{"a", "b", "c"}),
    lazy.ForEach(func(x string) { acc += x }),
)
// "abc"
Reduce
x, _ := lazy.Run2(
    lazy.FromSlice([]string{"a", "b", "c", "d"}),
    lazy.Reduce("foo", func(x, y string) string { return x + y }),
)
// "fooabcd"
Reduce1
x, _ := lazy.Run2(
    lazy.FromSlice([]int{1, 2, 3, 4}),
    lazy.Reduce1(func(x, y int) int { return x - y }),
)
// -8
SparkWith
x, _ := lazy.Run2(
    lazy.FromSlice([]int{1, 2, 3, 4}),
    lazy.SparkWith(
        lazy.Sum(),
        lazy.Count[int](),
        func(sum, count int) float64 {
            return float64(sum) / float64(count)
        },
    ),
)
// 2.5
assert.Equal(t, 2.5, x)
Spark
// import "github.com/shunkeen/eager/datatype/tuple"
tuple, _ := lazy.Run2(
    lazy.FromSlice([]int{0, 1, 2, 3, 4}),
    lazy.Spark(
        lazy.Sum(),
        lazy.ChainCS(
            lazy.Drop[int](2),
            lazy.Product(),
        ),
    ),
)
x, y := tuple()
// 10, 24
Other
Run1 -- Run12
h := lazy.ChainPD(
    lazy.FromSlice([]int{0, 1, 2, 3, 4}),
    lazy.Sum(),
)

x, _ := lazy.Run1(h)
// 10
x, _ := lazy.Run2(
    lazy.FromSlice([]int{0, 1, 2, 3, 4}),
    lazy.Sum(),
)
// 10
x, err := lazy.RunN!(
    instanceOfProducer,
    instanceOfProsumer1,
    instanceOfProsumer2,
    ...,
    instanceOfProsumerM, // M = N - 2
    instanceOfConsumer,
)
Chain2 -- Chain10
newProsumer := lazy.ChainN!(
    instanceOfProsumer1,
    instanceOfProsumer2,
    ...,
    instanceOfProsumerN,
)
ChainHM
newHermit := lazy.ChainHM(
    instanceOfProducer,
    instanceOfConsumer,
)
ChainPD
newProducer := lazy.ChainPD(
    instanceOfProducer,
    instanceOfProsumer,
)
ChainCS
newConsumer := lazy.ChainCS(
    instanceOfProsumer,
    instanceOfConsumer,
)

Contributors

License

Copyright © 2022 @shunkeen. This project is MIT licensed.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL