How to write first-class functions with context boundaries that can be called purely on a usage site?

For example, let's say I want to write a length function that returns the length of a given structure, given that it has an instance of a class of type length (from Scalaz) in scope.

Here's how I define it now:

 scala> def length[A, F[_] : Length]: F[A] => Int = _.len length: [A, F[_]](implicit evidence$1: scalaz.Length[F])F[A] => Int 

However, a call such as length(List(2, 3)) fails, because in this case the implicit parameter is the first argument required.

 scala> length(List(2, 3)) <console>:15: error: type mismatch; found : List[Int] required: scalaz.Length[?] length(List(2, 3)) ^ 

I thought length(implicitly)(List(2, 3)) would work, but it crashes sesssion (which is understandable, since type flows move from left to right). Providing explicit type annotations work, but it is unbearably ugly.

 scala> length(implicitly[Length[List]])(List(2, 3)) res16: Int = 2 

Is there a good way to write a first-class function, such as length , with a context binding that can be called as cleanly as regular functions on a usage site? (e.g. length(List(2, 3)) )

+4
source share
1 answer

Easy cheat!

 scala> def length[A, F[_] : Length]: F[A] => Int = _.len length: [A, F[_]](implicit evidence$1: scalaz.Length[F])F[A] => Int scala> List(2, 3) |> length res0: Int = 2 
+6
source

Source: https://habr.com/ru/post/1379160/


All Articles