2012-11-22 31 views
4

ToFunctorOps定義通過ToLiftV隱含一個lift方法,但我似乎無法讓它找到我的仿函數實例:如何使用升降機從ToFunctorOps

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的函子實例可見,但編譯器似乎無法找到它。任何關於如何解決這個問題的建議?

回答

2

我不明白爲什麼這不起作用(並且我剛纔詢問a follow-up question關於我不明白的部分),但我可以提供三種解決方法。

first對我沒有意義,需要對代碼和笨重的語法做一些更深入的更改,所以我只會順便提一提。

第二是導入相應FunctorSyntax implicits(相對於那些工作不正常的ToFunctorOps的):

scala> val of = implicitly[scalaz.Functor[Option]] 
of: scalaz.Functor[Option] = [email protected] 

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

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

但是這需要您導入這些implicits您想每一個人Functor使用它們,並沒有比寫作of lift inc更好。

最後需要多一點代碼,但更令人滿意。您需要以下新的語法特徵,與建模的liftFunction2Ops一個myLift方法:

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) 

這可能是值得把這個問題了上斯卡拉茨郵件列表。

+0

我不明白你的第二個解決方法的要求。這些進口應該就足夠了。 'import scalaz.std.AllInstances._'and'import scalaz.syntax.functor._' –

+1

@YoEight是的,這就是這個問題的要點:他們應該,但他們不應該。 – Hugh

+1

這是奇怪的行爲 - 非常好的挖掘。 – Hugh

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 

問題從FunctorSyntax使用LiftV特質來了。坦率地說,我懷疑它可能對某人有用。爲了工作,它必須明確鍵入:

import scalaz.syntax.functor._ 

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

2.some |> f.lift