2011-05-08 109 views

回答

17

給出更理論上的答案:const是SKI calculus的K組合子。當你使用相當抽象的概念時,有時候它會彈出,而你沒有太多的「工作」。考慮一個(Haskell風格)Functor特性:

trait Functor[F[_]] { 
    def fmap[A,B](f:A=>B, fa: F[A]):F[B] 
    //(<$) in Haskell 
    def left[A,B](a:A, fb:F[B]):F[A] 
} 

現在fmap需要是抽象的,因爲它是函子的本質。但是,我們可以寫留下了一般實現,在這裏,我們需要常量:

trait Functor[F[_]] { 
    def fmap[A,B](f:A=>B, fa: F[A]):F[B] 
    //(<$) in Haskell 
    def left[A,B](a:A, fb:F[B]):F[A] = 
    fmap(Function.const(a), fb) 
} 

測試與選項:

case object OptionFunctor extends Functor[Option] { 
    def fmap[A,B] (f:A=>B, fa:Option[A]):Option[B] = fa match { 
     case Some(a) => Some(f(a)) 
     case None => None 
    } 
} 

//left works: 
OptionFunctor.left("test",Some(42)) 
//--> Option[java.lang.String] = Some(test) 
OptionFunctor.left("test",None:Option[Int]) 
//--> Option[java.lang.String] = None 

正如你可以看到左邊做的事情應該(在一些仿函數包裝值當我們在第二個參數中已經有了這個仿函數的「角色模型」或「模式」)。定義它非常抽象而不知道函子種類的任何事情只能通過使用const來實現。

21

將它作爲參數傳遞給高階函數很有用。例如,與相同的元素替換列表中的所有元素:

scala> List(1, 2, 3, 4, 5).map(Function.const(7)) 
res1: List[Int] = List(7, 7, 7, 7, 7) 

你當然也可以寫

scala> List(1, 2, 3, 4, 5).map(_ => 7) 
res2: List[Int] = List(7, 7, 7, 7, 7) 

根據上下文,一個可能比其他更易讀。