Let us say we have the code (<: Monad[F] doesn't work as expected):
class External[F[_] <: Monad[F] : Concurrent](implicit proxy: Proxy[F]) { ... }
class Proxy[F[_] <: Monad[F]](implicit storage: Storage, async: Async[F]) {
def get(key: String): F[Option[Entry]] = {
async.blocking(storage.get(key))
}
}
I would like F[_] to be a Monad, so that proxy.get() have those traits and enables for example (inside External class):
proxy.get(key).flatMap(...)
So far so good, but when trying to instantiate with cats.effect.IO it doesn't work for External:
implicit val proxy: Proxy[IO] = new Proxy()
implicit val external: External[IO] = new External()
With error output:
inferred type arguments [[+A]cats.effect.IO[A]] do not conform to value <local External>'s type parameter bounds [F[_] <: cats.Monad[F]]
How can this be fixed or achieved in a different way?
Replace
class External[F[_] <: Monad[F] : Concurrent]
with
class External[F[_]: Monad : Concurrent]
Being a Monad doesn't mean being a subtype of Monad. It means there is an instance of the type class Monad for current type.
On contrary to OOP, in FP implementing some abstract behavior is achieved not with extending/inheritance/subtype polymorphism but with implicits/defining type-class instances/ad hoc polymorphism.
Maybe you need to import necessary syntax:
import cats.syntax.flatMap._
or
import cats.syntax.functor._
or all synaxes at once
import cats.syntax.all._
How to enforce F[_] to be an instance of Monad
https://eed3si9n.com/herding-cats/import-guide.html
Related
In scalaz when we define a module, we additionally define implicit, helper functions. Here is an example of definition and how it could be used by a client:
trait Functor[F[_]] {
def map[A,B](fa: F[A])(f: A => B): F[B]
}
object Functor {
def fmap[F[_], A,B](as:F[A])(f:A=>B)
(implicit ff:Functor[F]):F[B] =
ff.map(as)(f)
implicit val listFunctor = new Functor[List] {
def map[A,B](as: List[A])(f: A => B): List[B] = as map f
}
}
...
import com.savdev.NewLibrary._
val r = fmap(List(1,2))(_.toString)
final class FunctorOps[F[_], A](self: F[A])(implicit ff:Functor[F]){
def qmap[B](f:A=>B):F[B] = ff.map(self)(f)
}
trait ToFunctorOps {
implicit def ToFunctorOps[F[_],A](v: F[A])(implicit F0: Functor[F]) =
new FunctorOps[F,A](v)
}
object NewLibrary extends ToFunctorOps
...
import com.savdev.NewLibrary._
val r2 = List(1, 4) qmap (x=>x.toString)
The code is slightly changed. But the idea is that we define:
An abstraction and its API (algebra)
Define helper generic functions that use implicits and implicits themselves
Enrich existing types to be able to use our new abstraction. Implicit convertion is used for that. In scalaz we define a final class for a wrapper and implicit converters in traits
All above, the motivation of it and how it can be used by a client is clear. But in scalaz to each such module definition, there is also a related *Syntax class. I cannot understand the purpose of it. Can you please exlain, why it is needed and HOW it can be used in a client code.
In Scalaz it is defined as:
trait FunctorSyntax[F[_]] {
implicit def ToFunctorOps[A](v: F[A]): FunctorOps[F, A] =
new FunctorOps[F, A](v)(FunctorSyntax.this.F)
def F: Functor[F]
}
UPDATED:
Guys, it seems I am not clear enough, or a topic is more complicated for all of us.
What I need is to understand the difference between two traits:
trait ToFunctorOps {
implicit def ToFunctorOps[F[_],A](v: F[A])(implicit F0: Functor[F]) =
new FunctorOps[F,A](v)
}
vs.
trait FunctorSyntax[F[_]] {
implicit def ToFunctorOps[A](v: F[A]): FunctorOps[F, A] =
new FunctorOps[F, A](v)(FunctorSyntax.this.F)
def F: Functor[F]
}
Both traits define a generic method that creates FunctorOps, both have the same visibility rules.
The first ToFunctorOps trait, it is not generic itself, it defines only generic method with [F[_],A]. As a result, I can compose a lot of such traits into one object and import all of them at once. I gave an example how such traits could be used by a client:
object NewLibrary extends ToFunctorOps
...
import com.savdev.NewLibrary._
val r2 = List(1, 4) qmap (x=>x.toString)
This trait already gives clients a possibility to inject methods implicitly. Why do we need FunctorSyntax? This FunctorSyntax trait is a generic itself on [F[_]]. When I extend it, I must provide a type in the definition. Because F[_] now is used in trait definition, a function has less generic parameters, only [A].
I am asking you guys, if you can help and undestand, give me a code example how this FunctorSyntax trait can be used by a client. Exactly this is not clear.
Right now I see tries to explain the other topics, but not the original:
How to create implicit classes, instead of implicit functions.
Difference between final *Ops class and a trait, including their visibility. Here we compare 2 traits with the same visibility.
Explaining in general method injection, how they help. This functionality is provided already with ToFunctorOps.
Guys, again, please show the community USE CASES via CODE of FunctorSyntax. Code itself is always the best documentation.
Best regards
From what I can see in the scalaz codebase, I think that FunctorSyntax is meant as an alternative way of enabling syntax. They define Functor like this (simplified):
trait Functor {
def map[A, B](fa: F[A])(f: A => B): F[B]
val functorSyntax = new FunctorSyntax[F] { def F = Functor.this }
}
This enables the following way of working:
def foo[F[_]](f: F[String])(implicit F: Functor[F]): F[Int] = {
import F.functorSyntax._
f.map(_.length)
}
Compare to how ToFunctorOps adds syntax:
package scalaz.syntax { // simplified version of the scalaz codebase
object functor extends ToFunctorOps
}
import scalaz.syntax.functor._
def foo[F[_]: Functor](f: F[String]): F[Int] = f.map(_.length)
Here's a use case where you would use functorSyntax:
import org.scalatest.{FreeSpec, Matchers}
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}
import scala.concurrent.duration._
import scalaz._
import Scalaz._
import scala.language.postfixOps
class ScalazTest extends FreeSpec with Matchers {
"compose functors" in {
val composedFunctor = Functor[Future] compose Functor[List] compose Functor[Option]
import composedFunctor.functorSyntax._
val actual = Future.successful(List(Some(1), Some(2), None, Some(4))) fmap (x => x * 2)
Await.result(actual, 10 seconds) shouldBe List(Some(2), Some(4), None, Some(8))
}
}
The idea is that you can compose several functor instaces and import the final composed functor's instance in scope and work with it. Notice that fmap is resolved to composedFunctor.functorSyntax in this case and it works on 3 levels of nesting (Future[List[Option[Integer]]]) while still accepting a function that deals with primitive types.
How can I create an instance of a custom type constructor in Cats?
I know that cats already comes with almost all Scala built-in type constructors and I can import them by e.g import cats.data._ import cats.implicits._ import cats.instances._ but I would like to know how can I create my own implicit instance to work with monads operators sintaxs like >>= with my own custom type constructor. Suppose I have MyType[A] that is monadic o at least has flatMap and a pure constructor, I want to do things like:
Monad[MyType].pure(x) >>= { _.fooBar }
I saw at the sources of instances package to look at some examples like Option but it seems to be a lot to do, I don't know if there is an easy way.
regards.
Just provide an implicit instance of Monad for your type, and implement the required methods:
implicit object MyMonad extends Monad[MyType] {
def pure[A](x: A): MyType[A] = ???
def flatMap[A, B](fa: MyType[A])(f: A => MyType[B]): MyType[B] = ???
def tailRecM[A, B](a: A)(f: A => MyType[Either[A, B]]): MyType[B] = ???
}
If you are confident that your Monad is stack-safe, you can skip implementing tailRecM and extend StackSafeMonad[MyType] instead.
I have a generic F-bounded trait in Scala. Lets me write methods that return the same underlying implementation type, super! But now lets say a sub-trait also defines methods that require F-bounding. Scala is sending me back compile errors that don't make sense:
package sandbox
import sandbox.ComplexImpl.AnyComplexImpl
import scala.language.existentials
trait FBounded[IMPL <: FBounded[IMPL]] { self: IMPL =>
def foo: IMPL
}
trait FBoundedUser[F <: FBounded[F]] {
def bar(value: F): F = value.foo
}
trait SimpleImpl extends FBounded[SimpleImpl] {
override def foo: SimpleImpl = this
}
object SimpleUser extends FBoundedUser[SimpleImpl]
// A-OK so far...
trait ComplexImpl[IMPL <: ComplexImpl[IMPL]] extends FBounded[IMPL] { self: IMPL =>
def baz: IMPL
}
object ComplexImpl {
type AnyComplexImpl = ComplexImpl[T] forSome { type T <: ComplexImpl[T] }
}
object ComplexUser1 extends FBoundedUser[ComplexImpl[_]]
object ComplexUser2 extends FBoundedUser[AnyComplexImpl]
Trying to compile with either of ComplexUser1 or ComplexUser2 results in:
Error:(32, 29) type arguments [sandbox.ComplexImpl.AnyComplexImpl] do not conform to trait
FBoundedUser's type parameter bounds [F <: sandbox.FBounded[F]]
Which doesn't make sense to me. AnyComplexImpl definitely implements FBounded. Am I missing something, or is the type checker just failing me here?
EDIT:
class Concrete() extends ComplexImpl[Concrete] {
override def baz: Concrete = this
override def foo: Concrete = this
}
object ComplexUser3 extends FBoundedUser[Concrete]
Compiles just fine. So why won't the generic version?
The constraint requires AnyComplexImpl to implement FBounded[AnyComplexImpl], which it doesn't, not just FBounded[T] forSome { type T <: ComplexImpl[T] }.
It works if you make FBounded and ComplexImpl covariant. The compiler reasons that:
AnyComplexImpl is a supertype of any ComplexImpl[T], where T <: ComplexImpl[T];
So FBounded[T] forSome { type T <: ComplexImpl[T] } is a subtype of FBounded[AnyComplexImpl];
So AnyComplexImpl is a subtype of FBounded[AnyComplexImpl].
But I suspect trying to mix F-bounded types and existentials is likely to lead to other problems down the line. The reason ComplexUser1 and ComplexUser2 don't compile is precisely that they are not generic. Consider using actually generic version instead:
def complexUser4[T <: ComplexImpl[T]] = new FBoundedUser[T] {}
I am working with trees and lists of expressions (Exp, members removed for brevity).
sealed abstract class Exp
abstract class BinaryExp extends Exp
case class Add extends BinaryExp
Most of the time I use pattern matching to process a tree or list of expressions.
But sometimes this is a bit tedious and I want to be able to write:
if (exp.isBinary) ...
//or
exps.filter(_.isAdd) ...
But this would mean that I need to create all sorts of properties in Exp with an implementation like:
def isXXX = this.isInstanceOf[XXXExp]
My first attempt to make this generic does not work because of type erasure:
def is[T <: Exp] = this.isInstanceOf[T]
So I searched for a solution and found TypeTags:
http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html
Scala: What is a TypeTag and how do I use it?
Attempt with TypeTags does not work either:
sealed abstract class Exp {
// Cannot use isInstanceOf because of type erasure.
import reflect.runtime.universe._
def is[T <: Exp: TypeTag] = typeOf[this.type] <:< typeOf[T]
def as[T <: Exp] = asInstanceOf[T]
}
Is there a way in Scala to do this?
You can try Manifest (note that it is deprecated in 2.10).
sealed abstract class Exp {
def is[T <: Exp: Manifest] = implicitly[Manifest[T]].erasure.isInstance(this)
def as[T <: Exp] = asInstanceOf[T]
}
Example: http://ideone.com/47Q5W3
I want to define a Functor instances for the following classes:
class RequiresManifest[A: Manifest] {
def value: A
}
class RequiresAnyRef[A <: AnyRef] {
def value: A
}
class RequiresBothManifestAndAnyRef[A <: AnyRef: Manifest] {
def value: A
}
Is this possible ? Alternatively can a 'BoundedFunctor trait be defined ? something like this:
trait BoundedFunctor[F[_], Bound[_]] {
def fmap[A: Bound, B: Bound](r: F[A], f: A => B): F[B]
}
Here's my motivating example: How can I defined a Functor for the class TypedConverter.
import com.thoughtworks.xstream.converters.Converter
abstract class TypedConverter[A <: AnyRef: Manifest] extends Converter {
final def canConvert(klass: Class[_]) =
manifest[A].erasure.isAssignableFrom(klass)
final def marshal(value: AnyRef, writer: HierarchicalStreamWriter,
context: MarshallingContext) =
typedMarshal(value.asInstanceOf[A], writer, context)
final def unmarshal(reader: HierarchicalStreamReader,
context: UnmarshallingContext) =
typedUnmarshal(reader, context)
def typedMarshal(value: A, writer: HierarchicalStreamWriter,
context: MarshallingContext): Unit
def typedUnmarshal(reader: HierarchicalStreamReader,
context: UnmarshallingContext): A
}
This higher-kinded type has two constraints on its type parameter, first Manifest because that's used in the implementation of 'canConvert', second AnyRef because unmarshal requires an Object.
Actually I'm trying to create an InvariantFunctor, but Functor will do to start with.
See, in Math, a functor is a mapping from one category to another. In Comp Sci somehow people believe a functor is an endofunctor, e.g. for Scala discourse, it is defined on all Scala types.
That's how scalaz's implementation is written.
But it does not have to be so. As I understand, in your case you have a subcategory (roughly defined by Bound); so the functor will be from Bound to Scala.
It is a good idea in general, not much explored. I believe we have to go investigate this further. It is a little bit problematic though to explicitly define categories in programming languages. Not even sure about Agda.