map iterator i guess

master
Jordan Orelli 3 years ago
parent 1d343f3b22
commit 141f8d3e67

@ -81,23 +81,33 @@ func Max[T constraints.Ordered](src Able[T]) T {
return max return max
} }
type mapIter[T, Z any] struct {
fn func(T) Z
src Ator[T]
}
func (it mapIter[T, Z]) Next(v *Z) bool {
var t T
if !it.src.Next(&t) {
return false
}
*v = it.fn(t)
return true
}
func (it mapIter[T, Z]) Iter() Ator[Z] { return it }
func Map[T, Z any](src Able[T], f func(T) Z) Able[Z] {
return mapIter[T, Z]{fn: f, src: src.Iter()}
}
// Discarded Iterator types: // Discarded Iterator types:
// //
// This was my first attempt. I like to have a method that returns a bool so
// you can use it succinctly in a for loop, but I didn't love having to call
// both done and next
//
// type Ator[T any] interface { // type Ator[T any] interface {
// Done() bool // Done() bool
// Next() T // Next() T
// } // }
// //
// I was never optimistic about this. In practice, using this in a for loop is
// just annoying so I stopped doing it. But also there's another thing I find
// annoying: it's a copy every time. You're not really iterating over the
// values, you're iterating over copies of the values, it seemed like a lot of
// unecessary copying.
//
// type Ator[T any] interface { // type Ator[T any] interface {
// Next() (T, bool) // Next() (T, bool)
// } // }

@ -1,7 +1,5 @@
package iter package iter
import "constraints"
type slice[T any] []T type slice[T any] []T
type sliceIter[T any] struct { type sliceIter[T any] struct {
@ -22,5 +20,26 @@ func (it *sliceIter[T]) Iter() Ator[T] { return &sliceIter[T]{s: it.s} }
func (s slice[T]) Iter() Ator[T] { return &sliceIter[T]{s: s} } func (s slice[T]) Iter() Ator[T] { return &sliceIter[T]{s: s} }
// Slice takes a slice and returns an iterable backed by that slice // Slice takes a slice and returns an iterable backed by that slice.
func Slice[T constraints.Integer](s []T) Able[T] { return slice[T](s) } //
// ok so, asn an aside: normally you would write a function to return the
// concrete implementation, not an interface, but if I return the concrete
// implementation for an iter.Able, the type inference doesn't work correctly
// with the type parameters in some cases.
//
// So let's say we had an exported type Slice that was defined as:
//
// type Slice[T any] []T
//
// And we tried to convert a []int to a Slice[int], we could so that with:
//
// Slice([]int{1, 2, 3})
//
// And that would be fine until we try to do soething like pass it to Start.
// Returning Able[T] here means we can say Start(Slice([]int{1, 2, 3})), but if
// we had type Slice[T any] []T, we would have to say:
//
// Start[int](Slice([]int{1, 2, 3}))
//
// ...and I think that's annoying.
func Slice[T any](s []T) Able[T] { return slice[T](s) }

@ -0,0 +1,19 @@
package iter
import (
"testing"
"strconv"
)
func TestSlice(t *testing.T) {
nums := []int{1, 2, 3, 4, 5}
s := Slice(nums)
for n, it := Start(s); it.Next(&n); {
t.Log(n)
}
for n, it := Start(Map(Slice(nums), strconv.Itoa)); it.Next(&n); {
t.Log("fart " + n)
}
}

@ -1,56 +0,0 @@
package list
// type Iterable[T any] interface {
// Iter() Iter[T]
// }
//
// type Iter[T any] interface {
// Next(*T) bool
// }
// for v, it := iter.Ate(foods); it.Next(&v); {
//
// }
// This actually works, but for some reason I don't yet understand, defining
// Max with a constraint of constrains.Ordered that takes Iterable[T] cannot
// have its type parameter infered, but defining it with the same constraint of
// constraints.Ordered and taking List[T] does allow the type parameter to be
// inferred. Super confusing.
//
// func Max[T constraints.Ordered](l Iterable[T]) T {
// it := l.Iter()
//
// var v T
// if !it.Next(&v) {
// return v
// }
// max := v
// for it.Next(&v) {
// if v > max {
// max = v
// }
// }
// return max
// }
// Discarded Iterator types:
//
// This was my first attempt. I like to have a method that returns a bool so
// you can use it succinctly in a for loop, but I didn't love having to call
// both done and next
//
// type Iter[T any] interface {
// Done() bool
// Next() T
// }
//
// I was never optimistic about this. In practice, using this in a for loop is
// just annoying so I stopped doing it. But also there's another thing I find
// annoying: it's a copy every time. You're not really iterating over the
// values, you're iterating over copies of the values, it seemed like a lot of
// unecessary copying.
//
// type Iter[T any] interface {
// Next() (T, bool)
// }
Loading…
Cancel
Save