scala 斯卡拉猫,随机

2hh7jdfx  于 5个月前  发布在  Scala
关注(0)|答案(1)|浏览(49)

我正在尝试从猫那里学习函数随机数。这是大类中的方法:

def prepareDate(order: Model, zoneId: String): F[Instant] =
    Random[F].betweenLong(7200, 21600).flatMap { seconds =>
      order.dateTime
        .plusSeconds(seconds)
        .toInstant(ZoneOffset.of(zoneId))
        .asInstanceOf[F[Instant]]
    }

字符串
编译时出现No given instance of type cats.effect.std.Random[F] was found for parameter ev of method apply in object Random.错误
我试着这样把兰登放进去:

class SomeClass[F[_]: Async: Logger: Random]


但是不知道如何在对象伴随中隐含它。

k7fdbhmy

k7fdbhmy1#

让我们去除一些绒毛,因为逻辑本身与问题无关:

def prepareDate(): F[Long] =
  Random[F].betweenLong(7200, 21600)

字符串
所以... F[_]是什么?布泽尔会问你同样的问题。
如果你有一些F[_]的具体示例,例如cats.IO,那么整个事情就很简单了。你只需要获得一个Random[IO]的示例来处理,这可以用例如Random.scalaUtilRandom[IO]来完成(这给出了一个IO[Random[IO]],因此是flatMap):

def prepareDate(): IO[Long] = {
  Random.scalaUtilRandom[IO].flatMap(_.betweenLong(7200, 21600))
}


因此,您的问题实际上可以归结为-鉴于您不知道prepareDate的用户将使用什么作为F[_](可能是IO或其他东西),您打算如何证明在范围内会有Random[F]可用?
在定义prepareDate方法的上下文中,F[_]可能是一个泛型参数。如果它是一个类,那么你写的是正确的-class SomeClass[F[_]: Random]意味着F必须是一个更高级的类型(由于[_])并且在作用域中必须有一个可用的Random[F]。无论是谁用一些具体的F[_]示例化SomeClass的具体示例,都必须确保Random[F]在范围内。
下面是一些完整的代码:

import cats.effect.{ExitCode, IO, IOApp}
import cats.effect.std.Random

object Main extends IOApp {

  class MyDate[F[_]: Random] {
    def prepareDate(): F[Long] =
      Random[F].betweenLong(7200, 21600)

  }

  def run(args: List[String]): IO[ExitCode] = {
    Random.scalaUtilRandom[IO].flatMap { implicit random =>
      val myDate = new MyDate[IO]
      myDate.prepareDate().flatMap(IO.println).as(ExitCode.Success)
    }
  }

  // prints e.g. 17656
}


你提到了有一个伴随对象,但这并没有改变概念本身-你只是把“我需要一些在作用域中有Random[F]F[_]”从你的类定义移到你的方法定义:

object MyDate {
  def prepareDate[F[_]: Random](): F[Long] =
    Random[F].betweenLong(7200, 21600)
}

def run(args: List[String]): IO[ExitCode] = {
  Random.scalaUtilRandom[IO].flatMap { implicit random =>
    MyDate.prepareDate()(random).flatMap(IO.println).as(ExitCode.Success)
  }
}


顺便说一句,如果它对你或其他人有帮助的话:[F[_] : Random]只是[Random[F]]类型的隐式参数的语法糖。这同样可以工作,只是更冗长:

def prepareDate[F[_]]()(implicit random: Random[F]): F[Long] = ...

相关问题