2015-06-07 23 views
2

我已經明白瞭如何在我自己的例子類來創建一個仿函數時,它的參數是同一類型A.我可以在MyCaseClass [A,B]上創建Functor嗎?

case class MyCaseClass[A](a: A, b: A) 
val local = MyCaseClass[String]("One", "Two") 

implicit val myCaseClassFunctor = new Functor[MyCaseClass]{ 
    def map[A, B](fa: MyCaseClass[A])(f: A => B) = MyCaseClass(f(fa.a), f(fa.b)) 
} 
val F = Functor[MyCaseClass] 

val res = F.map(local)(_ + ".") 
println(res) 

在現實生活中的問題,一類情況是不會通過參數來形成的相同類型但不同的。

如果案件CLASE獲取要爲

case class MyCaseClass[A, B](a: A, b: B) 

這樣簡單的事情是否有可能建立一個仿函數呢?

我的猜測是,我不能從此地圖的定義與repect其類型相當明確的參數

def map[A, B] 

但我要問過,因爲這是我第一次編程函子。

回答

1

函子需要類型的單一類型的參數,是的,但你可以使用所謂type lambdas

implicit def myCaseClassFunctor[C] = new Functor[({type f[X] = MyCaseClass[C, X]})#f]{ 
    def map[A,B](fa: MyCaseClass[C,A])(f:A=>B) = MyCaseClass(fa.a, f(fa.b)) 
} 
3

一類具有兩個參數有兩個Functor S可能:一個第一字段映射另一個映射第二個領域。雖然這是解決方案,我建議定義一個Bifunctor,因爲它是更普遍的:

implicit val bifunctor = new Bifunctor[MyCaseClass] { 
    /** `map` over both type parameters. */ 
    def bimap[A, B, C, D](fab: MyCaseClass[A, B])(f: A => C, g: B => D): MyCaseClass[A, B] = 
    MaCaseClass(f(fab.a), g(fab.b)) 
} 

有一個Bifunctor例如,你可以很容易地得到一個Functor爲正確的參數或者左:

implicit def functor[X] = bifunctor.leftFunctor[X] 
// or 
implicit def functor[X] = bifunctor.rightFunctor[X] 
相關問題