Как написать первоклассные функции с границами контекста, которые можно без проблем вызывать при использовании сайта? - PullRequest
4 голосов
/ 01 ноября 2011

Например, допустим, я хочу написать функцию 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)))

1 Ответ

6 голосов
/ 01 ноября 2011

Полегче, чит!

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
...