0
votes

Comment éviter d'utiliser une projection de type dans SCALA

J'ai un emplacement de trait que je ne veux pas changer. o code> peut être une chaîne code> ou SEQ [String] CODE>

class Log[L <: Location](location: L)(implicit mapper: Mapper[L#O]) {
  def getPath(date: String): L#O =
    mapper.applyDate(location.value, date)

  def getPath(dates: Seq[String]): Seq[String] =
    mapper.applyDates(location.value, dates)
}

trait Mapper[A] {
  def applyDate(path: A, date: String): A
  def applyDates(path: A, dates: Seq[String]): Seq[String]
}

object Mapper {
  def build(path: String, date: String): String = s"$path/$date"

  implicit val stringMapper: Mapper[String] = new Mapper[String] {
    override def applyDate(path: String, date: String): String = build(path, date)
    override def applyDates(path: String, dates: Seq[String]): Seq[String] =
      dates.map(build(path, _))
  }
  implicit val seqStringMapper: Mapper[Seq[String]] = new Mapper[Seq[String]] {
    override def applyDate(path: Seq[String], date: String): Seq[String] =
      path.map(build(_, date))
    override def applyDates(path: Seq[String], dates: Seq[String]): Seq[String] =
      path.flatMap(p => dates.map(build(p, _)))
  }
}


4 commentaires

Pourquoi ne pas avoir o comme paramètre de type?


Principalement pour éviter d'avoir 2 paramètres de type dans le journal: Journal [O, L <: Emplacement [O]] . J'ai essayé tous les deux impliquer. Et je trouve un membre de type plus élégant dans ce cas.


Vous pouvez faire un journal [o] (emplacement: emplacement [O])


J'ai une réponse avec un paramètre de type que j'ai supprimé, mais change emplacement . Je peux l'onduler si tu veux


3 Réponses :


4
votes

Cela fonctionne pour moi: xxx pré>

qui peut être utilisé comme vous le souhaitez. p>


BTW, je vous recommanderais de rester à l'écart de SEQ STRUT> et utilisez une collection de béton comme Liste forte>. Voir Ce pour plus d'informations. P>


Modifier h3>

Assurer une instance LOG STRT> ne peut être créée que s'il existe un mapper et de garder l'emplacement encapsulé. P>

sealed trait Log[L <: Location] {
  protected type LL <: L
  protected val l: LL

  def getPath(date: String): l.O

  def getPath(dates: List[String]): List[String]
}

object Log {
  def apply[L <: Location](location: L)
                          (implicit mapper: Mapper[location.O]): Log[L] = new Log[L] {
    override protected final type LL = location.type                    
    override protected final val l: LL = location
    
    override def getPath(date: String): l.O =
      mapper.applyDate(l.value, date)

    override def getPath(dates: List[String]): List[String] =
        mapper.applyDates(l.value, dates)
  }
}


2 commentaires

Merci d'avoir souligné la question avec SEQ . 2 inconvénients avec votre proposition: il est possible d'instancier un journal qui n'a pas d'instances de mapper. L'emplacement est maintenant public (qui enfreint un peu l'encapsulation).


@Yannmoisan Voir la réponse modifiée, BTW Ceci obtient un complexe assez complexe car comme je vous l'ai dit auparavant, ce n'est pas clair quel est votre véritable objectif ultime. Par exemple, avez-vous vraiment besoin du type dépendant? Avez-vous vraiment besoin d'avoir le type précis l ? Une solution de contournement simple serait simplement en utilisant le modèle AUX comme Dmytro suggéré.



2
votes

Je ne vois aucune raison de ne pas utiliser simplement un paramètre de type ici.

class Log[O](location: Location[O])(implicit mapper: Mapper[O]) {
  def getPath(date: String): O =
    mapper.applyDate(location.value, date)
}

private val stringLog = new Log(new Location[String] {
  def value = "base"
})

private val seqStringLog = new Log(new Location[Seq[String]] {
  def value = Seq("foo", "bar")
})


0 commentaires

5
votes

Essayez de type raffiné

case class Log[_O](location: Location { type O = _O })(implicit mapper: Mapper[_O]) {
  def getPath(date: String): _O =
    mapper.applyDate(location.value, date)

  def getPath(dates: Seq[String]): Seq[String] =
    mapper.applyDates(location.value, dates)
}


0 commentaires