我是一个开发者,在经历了多年功能较少的scala之后,我试图把我的思想集中在类型级别堆栈(猫和猫效果)上。
我真的很难弯曲我的头周围的读者monad。我可以稍微遵循这里的例子:https://dev.to/riccardo_cardin/and-monads-for-almost-all-the-reader-monad-1ife,但是有一点完全让我困惑(作为一个来自更多OO背景的人),那就是我们为什么要做这一切?在我看来,最后,我们只是得到了一堆类型为
def myMethod(arg1: A, arg2: B): Reader[MyContext, MyMethodReturnType]
def myMethod2(arg1: A): Reader[MyContext, SomeOtherReturnType]
对我来说,这听起来像是一个类的OO概念的确切等价物:
class MyContext(/*class dependencies used by the methods*/) {
def myMethod(arg1: A, arg2: B): MyMethodReturnType
def myMethod2(arg1: A): SomeOtherReturnType
}
引用文章:
因此,Stocks依赖于StockRepository。我们如何在法典中表达这样的事实?我们不想使用构造函数注入机制或任何与之相关的东西。我们希望保持功能。
我的问题是为什么上面的引用似乎表明“保持功能性”本身就是一种奖励,但是你能给予我一个例子来展示不使用构造函数注入是一种优势吗?
谢谢!
1条答案
按热度按时间wlzqhblo1#
因此,Stocks依赖于StockRepository。我们如何在法典中表达这样的事实?我们不想使用构造函数注入机制或任何与之相关的东西。我们希望保持功能。
我要在这里对这篇文章提出质疑。我们确实想使用构造函数。*对象不是反FP的。 可变状态 * 是反FP的,但这并不意味着我们不能使用对象。
这不仅仅是我的观点-类型级生态系统中的库的 * 作者 * 也告诉你这样做,无论是明确的(认真地,去问他们)还是隐含的(观察几乎每个类型级库根本不使用Kleisli**)
在haskell中使用
Reader
是有意义的,在scala中则不然。我已经在typelevel生态系统代码库上工作了5年多,我几乎从来没有见过Reader(又名
Kleisli
)用于此,而且每次我这样做,它都很糟糕。只需使用函数参数或类构造函数。他们不可怕。类构造函数与Kleisli大致同构。你甚至注意到在你的问题中,“听起来像是一个类的OO概念的确切等价物”
当你需要一个API与组合函数相关的值时,使用Kleisli。Kleisli有意义的一个很好的例子是http 4s库。
使用Kleisli而不是类构造函数是让你的团队讨厌scala并提倡使用不同语言的好方法。