Golang Go语言中当没有 Generic 的时候,如何正确使用 monad?

发布于 1周前 作者 itying888 来自 Go语言

Golang Go语言中当没有 Generic 的时候,如何正确使用 monad?

已经被 OOP 虐得死去活来,看了几天函数编程思想,仿佛见到光明。

Go 已经很爽了,如果再加入函数编程思想就更爽了。目前有一些库实现了 monad 的原型,但在实际使用中遇到一些问题。由于 Go 没有 Generic,所以只能由 interface 去代替,这样导致编译阶段无法判断调用链中的参数类型是否匹配。

type Maybe struct {
  Val interface{}
  err error
}

即上一个函数输出的 Maybe.Val ,不一定匹配下一个函数的入参。 既然编译时无法发现错误,只能运行时发现了,我目前做法是写一个 HappyPath 的单元测试,跑过整个调用链。但我本来就是想用 monad 把大块的逻辑拆开各自做单元测试,现在又合回来了。

各位有没有经验分享一下?


更多关于Golang Go语言中当没有 Generic 的时候,如何正确使用 monad?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

Scala 欢迎你(逃

更多关于Golang Go语言中当没有 Generic 的时候,如何正确使用 monad?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


monad 是一种静态类型的机制
当你有动态机制时,那就没必要用这个。如果不是设计类型系统时就考虑到,那模拟出来是没意义的
用 reflect 包动态操作就行了,那些静态类型的概念全都可以略过,反正你不需要也做不到编译期的类型安全

还是缺泛型啊

没看懂,那你 Val 类型,改成某一个接口,而不是单纯的 interface{},不就行了吗

做不了,Go 缺乏必要的静态类型分析。就算做出个类似的,各种依赖运行时也完全是积累。

做好了也只是玩具吧,各种类型反射转换,性能渣渣了

在Go语言没有原生支持Generic(泛型)之前,使用monad(单子)的概念确实会稍显复杂,因为monads通常依赖于泛型来提供类型安全和复用性。不过,通过一些设计模式和接口技巧,我们仍然可以在Go中模拟monads的行为。

首先,要明确的是,monads是一种在函数式编程中用于处理计算序列、错误处理、状态管理等的抽象结构。在Go中,我们可以利用接口来定义monads的行为,并通过实现这些接口来创建具体的monad类型。

例如,为了处理错误,我们可以定义一个ErrorMonad接口,该接口包含一个返回可能错误结果的方法。然后,为不同的错误处理场景实现这个接口。

在没有泛型的情况下,我们需要为每种可能的类型实现这个接口。这会导致代码冗余,但它是模拟monads的一种可行方法。

另外,我们可以使用空接口interface{}来模拟泛型的行为,但这会牺牲类型安全,并需要在运行时进行类型断言。

为了简化代码和提高可读性,通常会结合使用结构体和类型断言来处理不同类型的值。

随着Go 1.18引入了泛型,现在可以使用泛型来定义monads,从而大大简化了代码并提高了类型安全性。如果你正在使用Go 1.18或更高版本,建议利用泛型来定义和实现monads。

总之,在没有泛型的情况下,虽然可以使用monads,但会牺牲一些类型安全和代码复用性。通过接口和空接口的使用,可以模拟出类似的行为。

回到顶部