4

ToFunctorOps通过隐式定义一个lift方法ToLiftV,但我似乎无法让它找到我的仿函数实例:

import scalaz.std.option._
import scalaz.syntax.functor._
import scalaz.syntax.id._
import scalaz.syntax.std.option._

def inc(x: Int) = x + 1

1.some |> (inc _).lift

<console>:16: error: could not find implicit value for parameter F: scalaz.Functor[F]
              1.some |> (inc _).lift

option 的仿函数实例是可见的,但编译器似乎找不到它。关于如何解决这个问题的任何建议?

4

2 回答 2

2

我不明白为什么这不起作用(我刚刚问了一个关于我不理解的部分的后续问题),但我可以提供三种解决方法。

一个对我来说没有意义,并且需要对您的代码和笨拙的语法进行一些更深入的更改,所以我只会顺便提一下。

第二个是导入适当的FunctorSyntax隐式(而不是ToFunctorOps那些不能正常工作的):

scala> val of = implicitly[scalaz.Functor[Option]]
of: scalaz.Functor[Option] = scalaz.std.OptionInstances$$anon$1@377d4c39

scala> import of.functorSyntax._
import of.functorSyntax._

scala> 1.some |> (inc _).lift
res0: Option[Int] = Some(2)

但这要求您为Functor要使用它们的每个人导入这些隐式,并且并不比仅编写of lift inc.

最后一个需要更多的代码,但更令人满意。您需要以下新的语法特征,以及以inmyLift为模型的方法:liftFunction2Ops

trait MyFunction1Syntax[A, R] extends scalaz.syntax.Ops[A => R] {
  def myLift[F[_]](implicit F: scalaz.Functor[F]) = F lift self
}

implicit def toMyFunction1Syntax[A, R](f: A => R) =
  new MyFunction1Syntax[A, R] { def self = f }

现在您可以编写以下内容:

scala> 1.some |> (inc _).myLift
res3: Option[Int] = Some(2)

在 Scalaz 邮件列表中提出这个问题可能是值得的。

于 2012-11-22T15:15:29.883 回答
0

您的问题可以像这样轻松解决

import scalaz.syntax.std.option._
import scalaz.std.option._
import scalaz.syntax.id._

implicit def liftIt[F[_], A, B](f: A => B)(implicit F: Functor[F]): F[A] => F[B] =
  F lift f

def inc(x: Int) = x + 1

2.some |> inc

问题来自LiftVFunctorSyntax 中使用的一个特征。坦率地说,我怀疑它可能对某人有用。为了工作,它必须明确输入:

import scalaz.syntax.functor._

val f: LiftV[Option, Int, Int] = (inc _)

2.some |> f.lift  
于 2012-11-26T11:25:45.233 回答