Skip to content

Latest commit

 

History

History
139 lines (91 loc) · 2.65 KB

README.md

File metadata and controls

139 lines (91 loc) · 2.65 KB

ginsu

CircleCI GoDoc

The ginsu library provides higher order functions mainly for slices.

Unfortunately golang does not support generics :(

Any type of slice can be wrapped in type T

Unfortunately higher order functions require the use of reflection, so they are not recommended for performance sensitve code.

supported higer order functions:

Apply(fn F, args ...T) (func()T, error)

AsyncRepeat(fn F, defered func()) func()

Compare(t0, t1 T, fn F) (bool, error)

Filter(t T, fn F) (T, error)

FilterNot(t T, fn F) (T, error)

ForAll(t T, fn F) (bool, error)

ForAny(t T, fn F) (bool, error)

ForEach(t T, fn F)

Map(t T, fn F) (T, error)

Reduce(initial, t T, fn F) (T, error)

Usage:

    // simple hof(s)

    // Apply
    fn, _ := Apply(F{func(a, b int) int {
	return a + b
    }}, T{1}, T{1})
    
    // res == 2
    res := fn().I.(int)

    // AsyncRepeat
    stop := AsyncRepeat(F{func() {
	// do something
    }}, func() {
        // do something defered
    })
    
    // stop doing something
    stop()


    // slice hof(s)

    type point struct {
        x, y int
    }
    
    type line struct {
        x, y point
    }
    
    td := struct {
        in, expect []point
    }{
        []point{{1, 1}, {2, 2}, {3, 3},{4, 4}},
        []point{{1, 1}, {2, 2}, {3, 3},{4, 4}},
    }
    

    // Compare
    ok, err := Compare(T{td.in}, T{td.expect}, F{func(p0, p1 point) bool {
        return p0 == p1
    }})


    // Filter
    res, err := Filter(T{td.in}, F{func(p point) bool {
        return (p.x % 2 == 0)
    }})

    result := res.I.([]point)


    // FilterNot
    res, _ := FilterNot(T{td.in}, F{func(p point) bool {
        return (p.x % 2 == 0)
    }})
    
    result := res.I.([]point)
    

    // ForAll
    ok, err := ForAll(T{td}, F{func(p point) bool {
        return (p.x == p.y)
    }})
  
  
    // ForAny
    ok, err := ForAny(T{td}, F{func(p point) bool {
        return (p == point{2, 2})
    }})
  

    // ForEach
    res := make([]point, len(td.expect))
    idx := 0
    ForEach(T{td.in}, F{func(p point) {
        res[idx] = point{p.x*2, p.y*2}
        idx++
    }})
  
    result := res.I.([]point)


    // Map
    res, _ := Map(T{in}, F{func(p point) line {
        return line{p, point{p.x*10, p.y*10}}
    }})
    
    result := res.I.([]line)


    // Reduce
    res, _ := Reduce(T{point{0,0}}, T{td}, F{func(acc, p point) point {
        return point{acc.x + p.x, acc.y + p.y}
    }})
    
    result := res.I.(point)