Scalaz 7, как использовать Functor с Function1 - PullRequest
1 голос
/ 04 мая 2019

Привет, я начинаю изучать Скалаз.

Я хочу получить функцию и сопоставить ее с другой функцией.

хотя я могу написать это:

import scalaz._, Scalaz._

import std.function._
import syntax.monad._

((x: Int) => x + 1) map {_ * 7}

и это работает, когда я использую явное appraoch согласно примерам в проекте github, оно не работает (см. Ниже)

import scalaz._, Scalaz._

import std.option._
import std.function._
import syntax.monad._

Functor[Function1[Int,Int]].map{x:Int => x * 4}{(x:Int) =>x * 7}

Я получаю как ошибку

Ошибка: (10, 17) Функция 1 принимает два типа параметров, ожидаемых: один Функтор [Function1] .map {x: Int => x * 4} {(x: Int) => x * 7}

Я вдохновился примером из документа, который работает

Functor[Option].map(Some("adsf"))(_.length)

Ответы [ 2 ]

2 голосов
/ 04 мая 2019

Расширяя последствия ((x: Int) => x * 4) map ((x: Int) => x * 7), мы получаем

ToFunctorOps(((x: Int) => x * 4))(function1Covariant) map ((x: Int) => x * 7)

Подпись function1Covariant is

implicit def function1Covariant[T]: Monad[T => ?] with ...

при подписи Functor.apply равно

def apply[F[_]](implicit F: Functor[F]): Functor[F] = F

Подставляя F[_] с ({type F[B] = Int => B})#F или используя kind-projector с Int => ?, мы заставляем apply требовать неявное

Functor[Int => ?]

, что удовлетворяется function1Covariant[Int]: Monad[Int => ?], поскольку Monad является типом Functor. Таким образом, мы могли бы написать явно

Functor[({type F[B] = Int => B})#F].map((x: Int) => x * 4)((x: Int) => x * 7)

или использовать кинопроектор как

Functor[Int => ?].map((x: Int) => x * 4)((x: Int) => x * 7)
0 голосов
/ 04 мая 2019

Я принял ответ выше, потому что он решает проблему.Это показывает, как сделать то, что я хотел сделать.Явно сделать функцию функтором, чтобы отобразить ее.Однако я остался немного недоволен тем, почему я должен сделать это ({type F[B] = Int => B})#F для функции?почему он не может быть полностью универсальным, почему библиотека не предоставляет этого «из коробки» вместо того, чтобы пользователь делал это.

Мне кажется, я нашел ответ в следующих постах:

Что такое лямбды типа в Scala и в чем их преимущества?

Зачем вводить лямбды?

Основываясь на этом, я пришел к выводу, что библиотека не может испечь это для вас, когда у вас нет F [X], например F [Int, INT] или Map [Int,INT].Нужно вручную прибегнуть к типу лямбда, который заставляет вас делать что-то частичноеСледовательно, мы не можем запекать что-то общее в библиотеке для FunctionX.

...