2011-09-05 111 views
11

的方法的条件调用我发现在我的代码这种模式好几次:在斯卡拉

if (doIt) 
    object.callAMethod 
    else 
    object 

我想知道是否有可能是上面写的代码语法上更加赏心悦目的方式,特别是为了避免重复变量object。喜欢的东西:

// using the Scalaz "pipe" operator 
    // and "pimping" f: T => T with a `when` method 
    object |> (_.callAMethod).when(doIt) 

不幸的是,线,因为类型推断需要(_.callAMethod)参数类型上面的失败。

我最好现在的做法是这样的:

implicit def doItOptionally[T](t: =>T) = new DoItOptionally(t) 
    class DoItOptionally[T](t: =>T) { 
     def ?>(f: T => T)(implicit doIt: Boolean = true) = 
     if (doIt) f(t) else t 
    } 

    implicit val doIt = true 
    object ?> (_.callAMethod) 

不是伟大的,因为我要申报implicit val但是如果有几个链接调用此不负有心人:

 object ?> (_.callAMethod) ?> (_.callAnotherMethod) 

有谁有更好的主意?我在这里错过了一些斯卡拉兹的魔法吗?

回答

16
class When[A](a: A) { 
    def when(f: A => Boolean)(g: A => A) = if (f(a)) g(a) else a 
} 
implicit def whenever[A](a: A) = new When(a) 

例子:

scala> "fish".when(_.length<5)(_.toUpperCase) 
res2: java.lang.String = FISH 
+0

我没想到反转的条件和功能,感谢! – Eric

+0

我还注意到,名词在这里比操作符更好,因为''.''需要在''fish''后面使用。 – Eric

2

,我不能对你的解答@Rex克尔,但更简洁的方式做评论,这将是:

implicit class When[A](a: A) { 
    def when(f: A => Boolean)(g: A => A) = if (f(a)) g(a) else a 
} 

只把implicit前该类允许您完全省略隐式函数。

0

如果您将callAMethod表示为自同态,则可以使用monoid功能。喜欢的东西:

object |> valueOrZero(doIt, Endo(_.callAMethod)) 

(可能需要在Endo类型参数)