2011-05-08 58 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) 

根据上下文,一个可能比其他更易读。