43 votes

Utilisez "carte" et des trucs sur Scala Tuples?

'map' préserve le nombre d'éléments, son utilisation sur un tuple semble donc judicieuse.

Mes tentatives jusqu'ici:

 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)
 

Cela semble assez douloureux ... Et je n'ai même pas commencé à essayer de le reconvertir en tuple.
Est-ce que je me trompe? La bibliothèque pourrait-elle être améliorée?

36voto

retronym Points 35066

En général, les types d'éléments d'un tuple ne sont pas les mêmes, de sorte que la carte n'a pas de sens. Vous pouvez définir une fonction pour gérer le cas particulier, même si:

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)

Vous pouvez utiliser le Pimp Ma Bibliothèque motif d'appel en ce qu' p.map(_ * 2).

Mise à JOUR

Même si les types des éléments qui ne sont pas les mêmes, Tuple2[A, B] est un Bifunctor, qui peuvent être mises en correspondance avec l' bimap de l'opération.

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)

Mise à JOUR 2

http://gist.github.com/454818

30voto

Miles Sabin Points 13604

informes prend en charge le mappage et de pliage sur les tuples par l'intermédiaire d'un HList de la représentation,

L'échantillon de RÉPLICATION de session,

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)

Lorsque les éléments du tuple sont de différents types, vous pouvez mapper une fonction polymorphe avec le type spécifique de cas,

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)

Mise à jour

Que d'informes 2.0.0-M1 cartographie plus de tuples est pris en charge directement. Les exemples ci-dessus ressemble maintenant à ceci,

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)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X