mirror of
https://github.com/golang/go
synced 2024-11-02 11:50:30 +00:00
dca9c11845
Add support for channels in subster.typ(). Add new test file chans.go. To support assignability of bidirectional channel args to directional channel params, I needed to type check generic calls after they are instantiated. (Eventually, we will create separate functions to just do the assignability logic, so we don't need to call the old typechecker in this case.) So, for generic calls, we now leave the call as OCALL (as a signal that the call still needs typechecking), and do typecheck.Call() during stenciling. Smaller changes: - Set the type of an instantiated OCLOSURE node (and not just the associated OFUNC node) - In instTypeName2, filter out the space that types2.TypeString inserts after a common in a typelist. Our standard naming requires no space after the comma. - With the assignability fix above, I no longer need the explicit conversions in cons.go. Change-Id: I148858bfc6708c0aa3f50bad7debce2b8c8c091f Reviewed-on: https://go-review.googlesource.com/c/go/+/301669 Trust: Dan Scales <danscales@google.com> Trust: Robert Griesemer <gri@golang.org> Reviewed-by: Robert Griesemer <gri@golang.org>
100 lines
2 KiB
Go
100 lines
2 KiB
Go
// run -gcflags=-G=3
|
|
|
|
// Copyright 2021 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// lice
|
|
|
|
package main
|
|
|
|
import "fmt"
|
|
|
|
// Overriding the predeclare "any", so it can be used as a type constraint or a type
|
|
// argument
|
|
type any interface{}
|
|
|
|
type _Function[a, b any] interface {
|
|
Apply(x a) b
|
|
}
|
|
|
|
type incr struct{ n int }
|
|
|
|
func (this incr) Apply(x int) int {
|
|
return x + this.n
|
|
}
|
|
|
|
type pos struct{}
|
|
|
|
func (this pos) Apply(x int) bool {
|
|
return x > 0
|
|
}
|
|
|
|
type compose[a, b, c any] struct {
|
|
f _Function[a, b]
|
|
g _Function[b, c]
|
|
}
|
|
|
|
func (this compose[a, b, c]) Apply(x a) c {
|
|
return this.g.Apply(this.f.Apply(x))
|
|
}
|
|
|
|
type _Eq[a any] interface {
|
|
Equal(a) bool
|
|
}
|
|
|
|
type Int int
|
|
|
|
func (this Int) Equal(that int) bool {
|
|
return int(this) == that
|
|
}
|
|
|
|
type _List[a any] interface {
|
|
Match(casenil _Function[_Nil[a], any], casecons _Function[_Cons[a], any]) any
|
|
}
|
|
|
|
type _Nil[a any] struct{
|
|
}
|
|
|
|
func (xs _Nil[a]) Match(casenil _Function[_Nil[a], any], casecons _Function[_Cons[a], any]) any {
|
|
return casenil.Apply(xs)
|
|
}
|
|
|
|
type _Cons[a any] struct {
|
|
Head a
|
|
Tail _List[a]
|
|
}
|
|
|
|
func (xs _Cons[a]) Match(casenil _Function[_Nil[a], any], casecons _Function[_Cons[a], any]) any {
|
|
return casecons.Apply(xs)
|
|
}
|
|
|
|
type mapNil[a, b any] struct{
|
|
}
|
|
|
|
func (m mapNil[a, b]) Apply(_ _Nil[a]) any {
|
|
return _Nil[b]{}
|
|
}
|
|
|
|
type mapCons[a, b any] struct {
|
|
f _Function[a, b]
|
|
}
|
|
|
|
func (m mapCons[a, b]) Apply(xs _Cons[a]) any {
|
|
return _Cons[b]{m.f.Apply(xs.Head), _Map[a, b](m.f, xs.Tail)}
|
|
}
|
|
|
|
func _Map[a, b any](f _Function[a, b], xs _List[a]) _List[b] {
|
|
return xs.Match(mapNil[a, b]{}, mapCons[a, b]{f}).(_List[b])
|
|
}
|
|
|
|
func main() {
|
|
var xs _List[int] = _Cons[int]{3, _Cons[int]{6, _Nil[int]{}}}
|
|
var ys _List[int] = _Map[int, int](incr{-5}, xs)
|
|
var xz _List[bool] = _Map[int, bool](pos{}, ys)
|
|
cs1 := xz.(_Cons[bool])
|
|
cs2 := cs1.Tail.(_Cons[bool])
|
|
_, ok := cs2.Tail.(_Nil[bool])
|
|
if cs1.Head != false || cs2.Head != true || !ok {
|
|
panic(fmt.Sprintf("got %v, %v, %v, expected false, true, true",
|
|
cs1.Head, cs2.Head, ok))
|
|
}
|
|
}
|