summaryrefslogtreecommitdiffstats
path: root/test/typeparam/issue50485.dir/a.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/typeparam/issue50485.dir/a.go')
-rw-r--r--test/typeparam/issue50485.dir/a.go239
1 files changed, 239 insertions, 0 deletions
diff --git a/test/typeparam/issue50485.dir/a.go b/test/typeparam/issue50485.dir/a.go
new file mode 100644
index 0000000..3a7c71a
--- /dev/null
+++ b/test/typeparam/issue50485.dir/a.go
@@ -0,0 +1,239 @@
+package a
+
+import "fmt"
+
+type ImplicitOrd interface {
+ ~int | ~int8 | ~int16 | ~int32 | ~int64 |
+ ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
+ ~float32 | ~float64 |
+ ~string
+}
+
+func LessGiven[T ImplicitOrd]() Ord[T] {
+ return LessFunc[T](func(a, b T) bool {
+ return a < b
+ })
+}
+
+type Eq[T any] interface {
+ Eqv(a T, b T) bool
+}
+
+type Ord[T any] interface {
+ Eq[T]
+ Less(a T, b T) bool
+}
+
+type LessFunc[T any] func(a, b T) bool
+
+func (r LessFunc[T]) Eqv(a, b T) bool {
+ return r(a, b) == false && r(b, a) == false
+}
+
+func (r LessFunc[T]) Less(a, b T) bool {
+ return r(a, b)
+}
+
+type Option[T any] struct {
+ v *T
+}
+
+func (r Option[T]) IsDefined() bool {
+ return r.v != nil
+}
+
+func (r Option[T]) IsEmpty() bool {
+ return !r.IsDefined()
+}
+
+func (r Option[T]) Get() T {
+ return *r.v
+}
+
+func (r Option[T]) String() string {
+ if r.IsDefined() {
+ return fmt.Sprintf("Some(%v)", r.v)
+ } else {
+ return "None"
+ }
+}
+
+func (r Option[T]) OrElse(t T) T {
+ if r.IsDefined() {
+ return *r.v
+ }
+ return t
+}
+
+func (r Option[T]) Recover(f func() T) Option[T] {
+ if r.IsDefined() {
+ return r
+ }
+ t := f()
+ return Option[T]{&t}
+}
+
+type Func1[A1, R any] func(a1 A1) R
+
+type Func2[A1, A2, R any] func(a1 A1, a2 A2) R
+
+func (r Func2[A1, A2, R]) Curried() Func1[A1, Func1[A2, R]] {
+ return func(a1 A1) Func1[A2, R] {
+ return Func1[A2, R](func(a2 A2) R {
+ return r(a1, a2)
+ })
+ }
+}
+
+type HList interface {
+ sealed()
+}
+
+// Header is constrains interface type, enforce Head type of Cons is HT
+type Header[HT any] interface {
+ HList
+ Head() HT
+}
+
+// Cons means H :: T
+// zero value of Cons[H,T] is not allowed.
+// so Cons defined as interface type
+type Cons[H any, T HList] interface {
+ HList
+ Head() H
+ Tail() T
+}
+
+type Nil struct {
+}
+
+func (r Nil) Head() Nil {
+ return r
+}
+
+func (r Nil) Tail() Nil {
+ return r
+}
+
+func (r Nil) String() string {
+ return "Nil"
+}
+
+func (r Nil) sealed() {
+
+}
+
+type hlistImpl[H any, T HList] struct {
+ head H
+ tail T
+}
+
+func (r hlistImpl[H, T]) Head() H {
+ return r.head
+}
+
+func (r hlistImpl[H, T]) Tail() T {
+ return r.tail
+}
+
+func (r hlistImpl[H, T]) String() string {
+ return fmt.Sprintf("%v :: %v", r.head, r.tail)
+}
+
+func (r hlistImpl[H, T]) sealed() {
+
+}
+
+func hlist[H any, T HList](h H, t T) Cons[H, T] {
+ return hlistImpl[H, T]{h, t}
+}
+
+func Concat[H any, T HList](h H, t T) Cons[H, T] {
+ return hlist(h, t)
+}
+
+func Empty() Nil {
+ return Nil{}
+}
+func Some[T any](v T) Option[T] {
+ return Option[T]{}.Recover(func() T {
+ return v
+ })
+}
+
+func None[T any]() Option[T] {
+ return Option[T]{}
+}
+
+func Ap[T, U any](t Option[Func1[T, U]], a Option[T]) Option[U] {
+ return FlatMap(t, func(f Func1[T, U]) Option[U] {
+ return Map(a, f)
+ })
+}
+
+func Map[T, U any](opt Option[T], f func(v T) U) Option[U] {
+ return FlatMap(opt, func(v T) Option[U] {
+ return Some(f(v))
+ })
+}
+
+func FlatMap[T, U any](opt Option[T], fn func(v T) Option[U]) Option[U] {
+ if opt.IsDefined() {
+ return fn(opt.Get())
+ }
+ return None[U]()
+}
+
+type ApplicativeFunctor1[H Header[HT], HT, A, R any] struct {
+ h Option[H]
+ fn Option[Func1[A, R]]
+}
+
+func (r ApplicativeFunctor1[H, HT, A, R]) ApOption(a Option[A]) Option[R] {
+ return Ap(r.fn, a)
+}
+
+func (r ApplicativeFunctor1[H, HT, A, R]) Ap(a A) Option[R] {
+ return r.ApOption(Some(a))
+}
+
+func Applicative1[A, R any](fn Func1[A, R]) ApplicativeFunctor1[Nil, Nil, A, R] {
+ return ApplicativeFunctor1[Nil, Nil, A, R]{Some(Empty()), Some(fn)}
+}
+
+type ApplicativeFunctor2[H Header[HT], HT, A1, A2, R any] struct {
+ h Option[H]
+ fn Option[Func1[A1, Func1[A2, R]]]
+}
+
+func (r ApplicativeFunctor2[H, HT, A1, A2, R]) ApOption(a Option[A1]) ApplicativeFunctor1[Cons[A1, H], A1, A2, R] {
+
+ nh := FlatMap(r.h, func(hv H) Option[Cons[A1, H]] {
+ return Map(a, func(av A1) Cons[A1, H] {
+ return Concat(av, hv)
+ })
+ })
+
+ return ApplicativeFunctor1[Cons[A1, H], A1, A2, R]{nh, Ap(r.fn, a)}
+}
+func (r ApplicativeFunctor2[H, HT, A1, A2, R]) Ap(a A1) ApplicativeFunctor1[Cons[A1, H], A1, A2, R] {
+
+ return r.ApOption(Some(a))
+
+}
+
+func Applicative2[A1, A2, R any](fn Func2[A1, A2, R]) ApplicativeFunctor2[Nil, Nil, A1, A2, R] {
+ return ApplicativeFunctor2[Nil, Nil, A1, A2, R]{Some(Empty()), Some(fn.Curried())}
+}
+func OrdOption[T any](m Ord[T]) Ord[Option[T]] {
+ return LessFunc[Option[T]](func(t1 Option[T], t2 Option[T]) bool {
+ if !t1.IsDefined() && !t2.IsDefined() {
+ return false
+ }
+ return Applicative2(m.Less).ApOption(t1).ApOption(t2).OrElse(!t1.IsDefined())
+ })
+}
+
+func Given[T ImplicitOrd]() Ord[T] {
+ return LessGiven[T]()
+}