Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 确保我的trait的type参数是Monad_Scala - Fatal编程技术网

Scala 确保我的trait的type参数是Monad

Scala 确保我的trait的type参数是Monad,scala,Scala,我已经写了这个代码 trait Input[F[_]] { def read: F[String] def write(str: String) : F[Unit] def getName : F[String] = for { _ <- write("What is your name") name <- read } yield name } trait输入[F[]]{ def read:F[字符串] def wr

我已经写了这个代码

trait Input[F[_]] {
    def read: F[String]
    def write(str: String) : F[Unit]
    def getName : F[String] = for {
        _ <- write("What is your name")
        name <- read
    } yield name
}
trait输入[F[]]{
def read:F[字符串]
def write(str:String):F[单位]
def getName:F[String]=for{

_
trait Input[F[\u]:Monad]
将创建隐式构造函数参数,trait不能有构造函数参数(直到Scala 3)。
def testFunc[F[\u]:Monad]
将创建隐式参数。例如:

def testFunc[F[_]: Monad](arg: Int) = ???
class TestClass[F[_]: Monad] {}
将工作,因为它被转换为:

def testFunc[F[_]](arg: Int)(implicit ev: Monad[F]) = ???
class TestClass[F[_]](implicit val ev: Monad[F]) {}
也就是说,
[F[\u]:Monad]
[F[\u]]
隐式valev:Monad[F]
的语法糖。在Scala 3之前,traits没有构造函数来传递参数

对于您的情况,例如,如果您确实需要在trait内部将
F
约束为
Monad
,那么:

trait Input[F[_]] {
  val M: Monad[F]

  def read: F[String]
  def write(str: String) : F[Unit]
  def getName : F[String] = M.flatMap(write("What is your name"))(_ => read)
}
也就是说,你对实现者说,“你可以实现
Input
,只要你有
Monad[F]
”。然后你可以像这样使用它:

object Main extends App{

  class IOInput extends Input[IO] {
    override val M: Monad[IO] = Monad[IO]
    override def read: IO[String] = IO("red")
    override def write(str: String): IO[Unit] = IO(println(s"write: $str"))
  }

  val impl = new IOInput

  println(impl.getName.unsafeRunSync())
}
但对我来说,似乎有点不对劲。你在trait
Input
中定义了一些效果,并在同一个trait中正确地使用了它们。至少对我来说这很奇怪。可能
getName
应该在其他地方。

问题不在于“因为约束在实际实现中起作用”。问题只是
trait Input[F][\u]:Monad]
将创建一个隐式构造函数参数,traits不能有构造函数参数(在Scala 3之前)。正如前面提到的:“traits不能有构造函数参数”,但是
抽象类可以,还有一些其他原因。
object Main extends App{

  class IOInput extends Input[IO] {
    override val M: Monad[IO] = Monad[IO]
    override def read: IO[String] = IO("red")
    override def write(str: String): IO[Unit] = IO(println(s"write: $str"))
  }

  val impl = new IOInput

  println(impl.getName.unsafeRunSync())
}