Skip to content
This repository has been archived by the owner on Mar 14, 2024. It is now read-only.

Commit

Permalink
add examples for Map contravariance and MapTo (generalization of Map …
Browse files Browse the repository at this point in the history
…+ Copy, since Copy alone doesn't work)
  • Loading branch information
Bryan C. Mills committed Jun 10, 2020
1 parent 732afd2 commit fda53e9
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 0 deletions.
30 changes: 30 additions & 0 deletions map.go2
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

// Map returns a new slice containig the result of applying f to each element in src.
func Map(type T1, T2)(src []T1, f func(T1) T2) []T2 {
dst := make([]T2, 0, len(src))
for _, x := range src {
dst = append(dst, f(x))
}
return dst
}

func recv(type T)(x <-chan T) T {
return <-x
}

func main() {
var chans []chan int

// To map the recv function over a slice of bidirectional channels,
// we need to wrap it: even though the element type "chan int"
// is assignable to the argument type, the two function types are distinct.
//
// (There is no way for Map to declare an argument type “assignable from T1”,
// so it must use “exactly T1” instead.)
vals := Map(chans, func(x chan int) int {
return recv(int)(x)
})

_ = vals
}
42 changes: 42 additions & 0 deletions mapto.go2
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package main

import (
"context"
"fmt"
"syscall"
)

// MapTo copies all of the elements in src to dst, using the supplied function
// to convert between the two.
func MapTo(type T2, T1)(dst []T2, src []T1, convert func(T1) T2) int {
for i, x := range src {
if i > len(dst) {
return i
}
dst[i] = convert(x)
}
return len(src)
}

func main() {
errnos := []syscall.Errno{syscall.ENOSYS, syscall.EINVAL}
errs := make([]error, len(errnos))

MapTo(errs, errnos, func(err syscall.Errno) error { return err })

for _, err := range errs {
fmt.Println(err)
}

cancelers := []context.CancelFunc{
func(){fmt.Println("cancel 1")},
func(){fmt.Println("cancel 2")},
}
funcs := make([]func(), len(cancelers))

MapTo(funcs, cancelers, func(f context.CancelFunc) func() { return f })

for _, f := range funcs {
f()
}
}

0 comments on commit fda53e9

Please sign in to comment.