猫:如何从隐式中找到特定类型

Cats: how to find the specific type from implicits

我有这段代码可以编译并且工作正常

import cats.implicits._
Cartesian[ValidResponse].product(
    getName(map).toValidated,
    readAge(map).toValidated
).map(User.tupled)

但是我不喜欢 cats.implicits._ 的导入,因为那里 类 太多了。我尝试导入与笛卡尔相关的特定内容,例如

import cats.implicits.catsSyntaxCartesian
import cats.implicits.catsSyntaxUCartesian
import cats.implicits.catsSyntaxTuple2Cartesian

但是这些都没有用。作为新手,我发现隐式导入非常混乱,因为它们只有 1000 多个,而且名称不是很明显。我唯一的选择就是通过import cats.implicits._导入整个宇宙并且停止考虑它。

事实上,我对 cats.implicitscats.instances._cats.syntax._ 有更广泛的困惑。到目前为止,我只是通过反复试验导入这些。我不太确定什么时候导入什么。

不要试图从 cats.implicits 中挑出具体的东西。您要么导入整个东西,要么根本不使用它。此外,没有理由害怕全部导入。它不能干扰任何东西。

好吧,我撒谎了。如果您将 cats.instances.<x>._ and/or cats.syntax.<x>._cats.implicits._ 一起导入,它 干扰。这些组是相互排斥的:您要么导入所有内容并使用 cats.implicits._ 忘记它,要么您专门 select 使用 cats.instancescats.syntax 导入您想要导入的内容。

这两个包不是 意味着像cats.implicits 一样完全导入。相反,they include a bunch of objects。每个对象都包含一些隐含的 instances/syntax,你打算从 那些 .

导入
import cats.implicits._ // Good, nothing to fear
// RESET IMPORTS
import cats.implicits.catsSyntaxCartesian // Bad, don't pick and choose
// RESET IMPORTS
import cats.instances._ // Bad, is useless
import cats.syntax._    // Ditto
// RESET IMPORTS
import cats.instances.list._   // ok
import cats.syntax.cartesian._ // ok
// RESET IMPORTS
import cats.implicits._
import cats.syntax.monad._ // Bad, don't mix these two

此外,每个 cats.{ instances, syntax } 包含一个 all 对象,具有明显的功能。导入 cats.implicits._ 实际上是 import cats.syntax.all._, cats.instances.all._.

的快捷方式

首先我会说 import cats.implicits._ 是安全、合理的,并且是开始时推荐的方法。因此,如果这个问题的唯一原因是您不喜欢导入太多 类,那么我认为您应该按原样咬住被欺负的东西。

另外,推荐大家看看官方的猫import guide。它试图解释猫代码的 package/logical 结构,并可能使其更容易理解。

"cats" 库分为几个 "areas",可以通过它们的包名称轻松区分:

  1. cats._ - 这是大多数类型类 居住的地方(例如 Monad、Foldable 等)
  2. cats.data._ - 这是 Validated 和 State 等数据结构的所在地。
  3. cats.instances._ - 这是 1 中定义的类型 类 的实例所在的位置。例如,如果您导入 cats.instances.list._,您将把标准列表的 Show、Monad 等实例纳入范围。 您最有可能对此感兴趣
  4. cats.syntax._ - 有一些语法丰富,使代码更易于编写和阅读。

使用 cats.syntax._ 的一个例子是:

import cats.Applicative
import cats.syntax.applicative._

val listOfInt = 5.pure[List]
//instead of 
val otherList = Applicative[List[Int]].pure(5)