使用scalaz'切换函数和对象|> [英] switch function and object with scalaz' |>
问题描述
当我想切换函数和对象时,我可以使用 scalaz
|>
运算符,这样可以获得更多的可读性.给大家介绍一个模型函数:
I can use scalaz
|>
operator when I want to switch function and object so there can be a little more readability acquired. Let me introduce you a model function :
def length2(x:String) = x.length * 2
现在,我可以用两种方式来写:
Now, I can write it in both ways:
"aoeu" |> length2
length2("aoeu")
但是如果我定义这个函数更通用,它就会停止工作.
But if I define this function more generic, it stops working.
def length2(x:SeqLike[_
,_
]) = x.length * 2
length2("aoeu") // ok
"aoeu" |> length2 // doesn't work
为什么编译器不明白这一点?在特征SeqLike
中肯定存在从String
到某些类混合的隐式转换.
Why the compiler doesn't understand this? There is definitely an implicit conversion from String
to some class mixing in trait SeqLike
.
推荐答案
scala> "aoeu" |> length2
<console>:14: error: type mismatch;
found : (scala.collection.SeqLike[_, _]) => Int
required: (java.lang.String) => ?
"aoeu" |> length2
错误信息非常清楚.
尽管存在从 String
到 SeqLike[_,_]
的隐式转换,但没有从 (SeqLike[_, _]) = 的转换>Int
到 String =>?
.
Although there is an implicit conversion from String
to SeqLike[_,_]
, there is no conversion from (SeqLike[_, _]) => Int
to String => ?
.
这可以使用以下隐式转换来修复:
This can be fixed using the following implicit conversion:
implicit def liftFun[X, T <% X, U](f: (X) => U): (T) => U = {
def g(t:T) = f(t)
g _
}
编辑 2:这是一个非 scalaz 运算符.
Edit 2: here is a non-scalaz operator.
class Pipe[T](t:T) {
def |%>[X, U](f: (X) => U)(implicit ev: T <%< X) = f(t)
}
implicit def toPipe[T](t:T) = new Pipe(t:T)
然后你可以这样使用它:
Then you can use it like this:
def l1(a:String) = a.length
def l2(a:Seq[_]) = a.length * 2
"abc" |%> l1
"abc" |%> l2
它允许 |%>
接受一个不能直接在 T
上工作但在 X
上工作的函数,只要有是从 T
到 X
的隐式转换的证据.
It allows |%>
to take a function that does not work directly on a T
but on a X
as long as there is evidence of an implicit conversion from T
to X
.
这篇关于使用scalaz'切换函数和对象|>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!