This repository has been archived by the owner on Mar 14, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add examples for Map contravariance and MapTo (generalization of Map …
…+ Copy, since Copy alone doesn't work)
- Loading branch information
Bryan C. Mills
committed
Jun 10, 2020
1 parent
732afd2
commit fda53e9
Showing
2 changed files
with
72 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} | ||
} |