Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Partially applied type constructor in Scala 3?

Reading "Learn You a Haskell for Great Good" and trying to understand how Haskell concepts of the book may be written in Scala 3.

chapter 11 mentions "partially applied type constructors" in section about Functions as Functors:

Another instance of Functor that we’ve been dealing with all along but didn’t know was a Functor is (->) r. You’re probably slightly confused now, since what the heck does (->) r mean? The function type r -> a can be rewritten as (->) r a, much like we can write 2 + 3 as (+) 2 3. When we look at it as (->) r a, we can see (->) in a slightly different light, because we see that it’s just a type constructor that takes two type parameters, just like Either. But remember, we said that a type constructor has to take exactly one type parameter so that it can be made an instance of Functor. That’s why we can’t make (->) an instance of Functor, but if we partially apply it to (->) r, it doesn’t pose any problems. If the syntax allowed for type constructors to be partially applied with sections (like we can partially apply + by doing (2+), which is the same as (+) 2), you could write (->) r as (r ->)

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

instance Functor ((->) r) where  
    fmap f g = (\x -> f (g x))  

I understand all this logic in the book + the fact that Haskell deals with type constructors just as with usual functions – those can be curried and partially applied.

Question:

What is Scala 3 analogue of such partially applied type constructor so we might define fmap in the way that visually resembles below Haskell definition?

(it is smth that can be modelled with higer-kinded types?)

>Solution :

In Scala 3 you can use type lambdas

trait Functor[F[_]]:
  def map[A, B](f: A => B)(fa: F[A]): F[B]
given [R]: Functor[[X] =>> R => X] with
  override def map[A, B](f: A => B)(fa: R => A): R => B = fa andThen f

or kind projector (scalacOptions += "-Ykind-projector")

given [R]: Functor[R => *] with
  override def map[A, B](f: A => B)(fa: R => A): R => B = fa andThen f

Eventually this should become

given [R]: Functor[R => _] with
  override def map[A, B](f: A => B)(fa: R => A): R => B = fa andThen f

Polymorphic method works with type lambda, but not with type wildcard in Scala 3

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading