Например, допустим, я хочу написать функцию length
, которая возвращает длину заданной структуры, учитывая, что у нее есть экземпляр типа class Length
(из Scalaz) в области видимости.
Вот как я сейчас ее определяю:
scala> def length[A, F[_] : Length]: F[A] => Int = _.len
length: [A, F[_]](implicit evidence$1: scalaz.Length[F])F[A] => Int
Однако вызов, такой как length(List(2, 3))
, завершается неудачно, поскольку в этом случае неявный параметр является первым требуемым аргументом.
scala> length(List(2, 3))
<console>:15: error: type mismatch;
found : List[Int]
required: scalaz.Length[?]
length(List(2, 3))
^
Я думал, что length(implicitly)(List(2, 3))
сработает, но в конечном итоге это приведет к краху сеанса (что понятно, поскольку вывод типа течет слева направо). Предоставление явной аннотации типов работает, но это невыносимо уродливо.
scala> length(implicitly[Length[List]])(List(2, 3))
res16: Int = 2
Есть ли хороший способ написать функцию первого класса, такую как length
, имеющую привязку к контексту, которую можно вызывать так же чисто, как и обычные функции на сайте использования? (как length(List(2, 3))
)