Ensure that the type parameter for my trait is a Monad
up vote
1
down vote
favorite
I have written this code
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
This code doesn't compile obviously because the compiler has no way of knowing that the type F supports flatmap. So I change my code to
import scalaz._
import Scalaz._
trait Input[F[_] : Monad]
def read: F[String]
def write(str: String) : F[Unit]
def getName : F[String] = for
_ <- write("What is your name")
name <- read
yield name
but now I get compile time error traits cannot have type parameters with context bounds
.
So how can I specify constraints on my type parameter so that it always supports flatmap?
scala
add a comment |
up vote
1
down vote
favorite
I have written this code
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
This code doesn't compile obviously because the compiler has no way of knowing that the type F supports flatmap. So I change my code to
import scalaz._
import Scalaz._
trait Input[F[_] : Monad]
def read: F[String]
def write(str: String) : F[Unit]
def getName : F[String] = for
_ <- write("What is your name")
name <- read
yield name
but now I get compile time error traits cannot have type parameters with context bounds
.
So how can I specify constraints on my type parameter so that it always supports flatmap?
scala
1
As has been noted: "traits can't have constructor parameters," but anabstract class
can, and there are a few other reasons you might prefer an abstract class instead of a trait.
– jwvh
Nov 11 at 7:35
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have written this code
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
This code doesn't compile obviously because the compiler has no way of knowing that the type F supports flatmap. So I change my code to
import scalaz._
import Scalaz._
trait Input[F[_] : Monad]
def read: F[String]
def write(str: String) : F[Unit]
def getName : F[String] = for
_ <- write("What is your name")
name <- read
yield name
but now I get compile time error traits cannot have type parameters with context bounds
.
So how can I specify constraints on my type parameter so that it always supports flatmap?
scala
I have written this code
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
This code doesn't compile obviously because the compiler has no way of knowing that the type F supports flatmap. So I change my code to
import scalaz._
import Scalaz._
trait Input[F[_] : Monad]
def read: F[String]
def write(str: String) : F[Unit]
def getName : F[String] = for
_ <- write("What is your name")
name <- read
yield name
but now I get compile time error traits cannot have type parameters with context bounds
.
So how can I specify constraints on my type parameter so that it always supports flatmap?
scala
scala
asked Nov 10 at 20:04
Knows Not Much
10.1k2598196
10.1k2598196
1
As has been noted: "traits can't have constructor parameters," but anabstract class
can, and there are a few other reasons you might prefer an abstract class instead of a trait.
– jwvh
Nov 11 at 7:35
add a comment |
1
As has been noted: "traits can't have constructor parameters," but anabstract class
can, and there are a few other reasons you might prefer an abstract class instead of a trait.
– jwvh
Nov 11 at 7:35
1
1
As has been noted: "traits can't have constructor parameters," but an
abstract class
can, and there are a few other reasons you might prefer an abstract class instead of a trait.– jwvh
Nov 11 at 7:35
As has been noted: "traits can't have constructor parameters," but an
abstract class
can, and there are a few other reasons you might prefer an abstract class instead of a trait.– jwvh
Nov 11 at 7:35
add a comment |
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
trait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3). def testFunc[F[_]: Monad]
would create an implicit parameter. For instance:
def testFunc[F[_]: Monad](arg: Int) = ???
class TestClass[F[_]: Monad]
Will work because it is translated to:
def testFunc[F[_]](arg: Int)(implicit ev: Monad[F]) = ???
class TestClass[F[_]](implicit val ev: Monad[F])
I.e. [F[_]: Monad]
is syntactic sugar for [F[_]]
with implicit val ev: Monad[F]
. And traits has no constructor to pass parameters until Scala 3.
For your case, if you really need to inside a trait to constraint F
to a Monad
for example, then:
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)
I.e. you are saying to one who implements, that "you can implement Input
, as soon as you have Monad[F]
". Then you can use it like:
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())
P.S. But for me, it seems like something is wrong. You are kinda defining effects in trait Input
and using them right in the same trait. Reads weird for me at least. Probably getName
should be somewhere else.
2
The problem is not "Because constraints work on actual implementations." It's just thattrait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3).
– Alexey Romanov
Nov 11 at 7:11
@AlexeyRomanov, thanks, updated
– muradm
Nov 11 at 7:17
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
trait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3). def testFunc[F[_]: Monad]
would create an implicit parameter. For instance:
def testFunc[F[_]: Monad](arg: Int) = ???
class TestClass[F[_]: Monad]
Will work because it is translated to:
def testFunc[F[_]](arg: Int)(implicit ev: Monad[F]) = ???
class TestClass[F[_]](implicit val ev: Monad[F])
I.e. [F[_]: Monad]
is syntactic sugar for [F[_]]
with implicit val ev: Monad[F]
. And traits has no constructor to pass parameters until Scala 3.
For your case, if you really need to inside a trait to constraint F
to a Monad
for example, then:
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)
I.e. you are saying to one who implements, that "you can implement Input
, as soon as you have Monad[F]
". Then you can use it like:
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())
P.S. But for me, it seems like something is wrong. You are kinda defining effects in trait Input
and using them right in the same trait. Reads weird for me at least. Probably getName
should be somewhere else.
2
The problem is not "Because constraints work on actual implementations." It's just thattrait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3).
– Alexey Romanov
Nov 11 at 7:11
@AlexeyRomanov, thanks, updated
– muradm
Nov 11 at 7:17
add a comment |
up vote
1
down vote
accepted
trait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3). def testFunc[F[_]: Monad]
would create an implicit parameter. For instance:
def testFunc[F[_]: Monad](arg: Int) = ???
class TestClass[F[_]: Monad]
Will work because it is translated to:
def testFunc[F[_]](arg: Int)(implicit ev: Monad[F]) = ???
class TestClass[F[_]](implicit val ev: Monad[F])
I.e. [F[_]: Monad]
is syntactic sugar for [F[_]]
with implicit val ev: Monad[F]
. And traits has no constructor to pass parameters until Scala 3.
For your case, if you really need to inside a trait to constraint F
to a Monad
for example, then:
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)
I.e. you are saying to one who implements, that "you can implement Input
, as soon as you have Monad[F]
". Then you can use it like:
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())
P.S. But for me, it seems like something is wrong. You are kinda defining effects in trait Input
and using them right in the same trait. Reads weird for me at least. Probably getName
should be somewhere else.
2
The problem is not "Because constraints work on actual implementations." It's just thattrait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3).
– Alexey Romanov
Nov 11 at 7:11
@AlexeyRomanov, thanks, updated
– muradm
Nov 11 at 7:17
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
trait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3). def testFunc[F[_]: Monad]
would create an implicit parameter. For instance:
def testFunc[F[_]: Monad](arg: Int) = ???
class TestClass[F[_]: Monad]
Will work because it is translated to:
def testFunc[F[_]](arg: Int)(implicit ev: Monad[F]) = ???
class TestClass[F[_]](implicit val ev: Monad[F])
I.e. [F[_]: Monad]
is syntactic sugar for [F[_]]
with implicit val ev: Monad[F]
. And traits has no constructor to pass parameters until Scala 3.
For your case, if you really need to inside a trait to constraint F
to a Monad
for example, then:
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)
I.e. you are saying to one who implements, that "you can implement Input
, as soon as you have Monad[F]
". Then you can use it like:
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())
P.S. But for me, it seems like something is wrong. You are kinda defining effects in trait Input
and using them right in the same trait. Reads weird for me at least. Probably getName
should be somewhere else.
trait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3). def testFunc[F[_]: Monad]
would create an implicit parameter. For instance:
def testFunc[F[_]: Monad](arg: Int) = ???
class TestClass[F[_]: Monad]
Will work because it is translated to:
def testFunc[F[_]](arg: Int)(implicit ev: Monad[F]) = ???
class TestClass[F[_]](implicit val ev: Monad[F])
I.e. [F[_]: Monad]
is syntactic sugar for [F[_]]
with implicit val ev: Monad[F]
. And traits has no constructor to pass parameters until Scala 3.
For your case, if you really need to inside a trait to constraint F
to a Monad
for example, then:
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)
I.e. you are saying to one who implements, that "you can implement Input
, as soon as you have Monad[F]
". Then you can use it like:
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())
P.S. But for me, it seems like something is wrong. You are kinda defining effects in trait Input
and using them right in the same trait. Reads weird for me at least. Probably getName
should be somewhere else.
edited Nov 11 at 7:17
answered Nov 10 at 20:29
muradm
732419
732419
2
The problem is not "Because constraints work on actual implementations." It's just thattrait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3).
– Alexey Romanov
Nov 11 at 7:11
@AlexeyRomanov, thanks, updated
– muradm
Nov 11 at 7:17
add a comment |
2
The problem is not "Because constraints work on actual implementations." It's just thattrait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3).
– Alexey Romanov
Nov 11 at 7:11
@AlexeyRomanov, thanks, updated
– muradm
Nov 11 at 7:17
2
2
The problem is not "Because constraints work on actual implementations." It's just that
trait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3).– Alexey Romanov
Nov 11 at 7:11
The problem is not "Because constraints work on actual implementations." It's just that
trait Input[F[_]: Monad]
would create an implicit constructor parameter and traits can't have constructor parameters (until Scala 3).– Alexey Romanov
Nov 11 at 7:11
@AlexeyRomanov, thanks, updated
– muradm
Nov 11 at 7:17
@AlexeyRomanov, thanks, updated
– muradm
Nov 11 at 7:17
add a comment |
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53242943%2fensure-that-the-type-parameter-for-my-trait-is-a-monad%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
As has been noted: "traits can't have constructor parameters," but an
abstract class
can, and there are a few other reasons you might prefer an abstract class instead of a trait.– jwvh
Nov 11 at 7:35