Eld*_*rum 43 dictionary scala tuples shapeless
'map'保留了元素的数量,因此在元组上使用它似乎是明智的.
到目前为止我的尝试:
scala> (3,4).map(_*2)
error: value map is not a member of (Int, Int)
(3,4).map(_*2)
^
scala> (3,4).productIterator.map(_*2)
error: value * is not a member of Any
(3,4).productIterator.map(_*2)
^
scala> (3,4).productIterator.map(_.asInstanceOf[Int]*2)
res4: Iterator[Int] = non-empty iterator
scala> (3,4).productIterator.map(_.asInstanceOf[Int]*2).toList
res5: List[Int] = List(6, 8)
Run Code Online (Sandbox Code Playgroud)
它看起来很痛苦......我甚至还没有开始尝试将它转换回元组.
我做错了吗?图书馆可以改进吗?
ret*_*nym 35
一般来说,元组的元素类型不一样,因此map没有意义.但是,您可以定义一个函数来处理特殊情况:
scala> def map[A, B](as: (A, A))(f: A => B) =
as match { case (a1, a2) => (f(a1), f(a2)) }
map: [A,B](as: (A, A))(f: (A) => B)(B, B)
scala> val p = (1, 2)
p: (Int, Int) = (1,2)
scala> map(p){ _ * 2 }
res1: (Int, Int) = (2,4)
Run Code Online (Sandbox Code Playgroud)
您可以使用Pimp My Library模式将其称为p.map(_ * 2).
UPDATE
即使元素的类型不相同,Tuple2[A, B]也是一个Bifunctor,它可以与bimap操作一起映射.
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> val f = (_: Int) * 2
f: (Int) => Int = <function1>
scala> val g = (_: String) * 2
g: (String) => String = <function1>
scala> f <-: (1, "1") :-> g
res12: (Int, String) = (2,11)
Run Code Online (Sandbox Code Playgroud)
更新2
Mil*_*bin 29
无形状支持通过中间HList表示映射和折叠元组,
示例REPL会话,
scala> import shapeless._ ; import Tuples._
import shapeless._
import Tuples._
scala> object double extends (Int -> Int) (_*2)
defined module double
scala> (3, 4).hlisted.map(double).tupled
res0: (Int, Int) = (6,8)
Run Code Online (Sandbox Code Playgroud)
在元组的元素具有不同类型的情况下,您可以使用具有特定类型的情况的多态函数进行映射,
scala> object frob extends Poly1 {
| implicit def caseInt = at[Int](_*2)
| implicit def caseString = at[String]("!"+_+"!")
| implicit def caseBoolean = at[Boolean](!_)
| }
defined module frob
scala> (23, "foo", false, "bar", 13).hlisted.map(frob).tupled
res1: (Int, String, Boolean, String, Int) = (46,!foo!,true,!bar!,26)
Run Code Online (Sandbox Code Playgroud)
更新
对于无形的2.0.0-M1映射,直接支持元组.以上示例现在看起来像这样,
scala> import shapeless._, poly._, syntax.std.tuple._
import shapeless._
import poly._
import syntax.std.tuple._
scala> object double extends (Int -> Int) (_*2)
defined module double
scala> (3, 4) map double
res0: (Int, Int) = (6,8)
scala> object frob extends Poly1 {
| implicit def caseInt = at[Int](_*2)
| implicit def caseString = at[String]("!"+_+"!")
| implicit def caseBoolean = at[Boolean](!_)
| }
defined module frob
scala> (23, "foo", false, "bar", 13) map frob
res1: (Int, String, Boolean, String, Int) = (46,!foo!,true,!bar!,26)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
17335 次 |
| 最近记录: |