Go中的依赖类型的通用类型推断

huangapple go评论85阅读模式
英文:

Generic type inference with dependent types in Go

问题

我想从big包中获得大数运算的辅助函数。其中之一是IsZero,它接受big.(Int|Float|Rat)类型的参数,如果这个大数等于零则返回true,否则返回false

我这样实现了它:

package main

import (
	"fmt"
	"math/big"
)

type Target interface {
	big.Int | big.Float | big.Rat
}

type Comparable[T Target] interface {
	Cmp(*T) int
}

func IsZero[C Comparable[T], T Target](a C) bool {
	var t T

	return a.Cmp(&t) == 0
}

如果我显式指定泛型参数,它可以正常工作:

func main() {
	fmt.Println(IsZero[Comparable[big.Int], big.Int](big.NewInt(0)))
}

但是,如果我尝试让Go为我推断泛型参数,它就无法工作:

func main() {
	fmt.Println(IsZero(big.NewInt(0)))
}
./prog.go:25:20: cannot infer T (prog.go:18:30)

是否有可能解决这个问题?

英文:

I want to have helpers for big maths from big package. One of them is IsZero which accepts big.(Int|Float|Rat) and returns true if this big number equals to zero and false if not.

I did it that way:

package main

import (
	"fmt"
	"math/big"
)

type Target interface {
	big.Int | big.Float | big.Rat
}

type Comparable[T Target] interface {
	Cmp(*T) int
}

func IsZero[C Comparable[T], T Target](a C) bool {
	var t T

	return a.Cmp(&t) == 0
}

And it works if I specify generic arguments explicitly:

func main() {
	fmt.Println(IsZero[Comparable[big.Int], big.Int](big.NewInt(0)))
}

But if I try to make Go infer them for me, it doesn't work:

func main() {
	fmt.Println(IsZero(big.NewInt(0)))
}
./prog.go:25:20: cannot infer T (prog.go:18:30)

Is there a possible workaround for this?

答案1

得分: 2

有没有可能的解决方法?没有,除非希望下一个Go版本中的推理更加智能。- Volker

你只能简化IsZero函数:

func IsZero[T Target](a Comparable[T]) bool {
	var t T

	return a.Cmp(&t) == 0
}
func main() {
	fmt.Println(IsZero[big.Int](big.NewInt(0)))

	var b Comparable[big.Int] = big.NewInt(0)
	fmt.Println(IsZero(b))
}
英文:

> "Is there a possible workaround for this?" No, except hope inference will be smarter in the next Go version. –
Volker

Your can only simplify IsZero function:

func IsZero[T Target](a Comparable[T]) bool {
	var t T

	return a.Cmp(&t) == 0
}
func main() {
	fmt.Println(IsZero[big.Int](big.NewInt(0)))

	var b Comparable[big.Int] = big.NewInt(0)
	fmt.Println(IsZero(b))
}

huangapple
  • 本文由 发表于 2022年8月3日 02:25:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/73212115.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定