简体   繁体   中英

Creating arbitary Higher Kinded Types in Scala

Right from the start I'm not absolutely sure I have the right approach to solving my issue. I'm looking for two different answers here:

  1. Alternative ideas to the problem are welcomed, but also,
  2. I'd like to understand how can I make the example below work - or what is it that I'm missing about higher kinded types that means the approach is wrong?

I have "things" that I wish to dynamically (eventually at run-time) add different attributes to. For example a "Document" thing may have an Address attribute. Another "Document" thing may have an "To eMail Address" attribute. A third "Document" thing may have both attributes.

The code below shows Contained (which may represent various things) and a Thing (which is one of those).

It also includes two HigherKindedType traits, which are the attributes I wish to dynamically add to the Contained things.

I can't create a type of "arbitrary type with attribute", which I was hoping to do in the ContainedOps class.

Please help me complete the ??? parts.

package example

import scala.language.higherKinds

trait Contained[A]
case class Thing(id: String) extends Contained[Thing]

//case class Attribute(value: String) // needed ?

trait WithAttribute[F[_]] {
  def attribute[A, B](fa: F[A])(f: A => B) : F[B]
}

trait WithAnotherAttribute[F[_]] {
  def anotherAttribute[A, B](fa: F[A])(f: A => B) : F[B]
}

object Contained {

  implicit class ContainedOps[A](c: Contained[A]) {

    type AWithAttribute = A with WithAttribute[Contained]
    def withAttribute(value: String): AWithAttribute = ???

    type AWithAnotherAttribute = A with WithAnotherAttribute[Contained]
    def withAnotherAttribute(value: String): AWithAnotherAttribute = ???

  }

}

object Example extends App {

  val thing = Thing("one")
  println(s"thing: $thing")

  val thingWithAttribute = thing.withAttribute("attributeValue")
  println(s"thingWithAttribute: $thingWithAttribute")

  val thingWithAnotherAttribute = thing.withAnotherAttribute("anotherAttributeValue")
  println(s"thingWithAnotherAttribute: $thingWithAnotherAttribute")

  val thingWithAttributeWithAnotherAttribute = thingWithAttribute.withAnotherAttribute("anotherAttributeValue")
  println(s"thingWithAttributeWithAnotherAttribute: $thingWithAttributeWithAnotherAttribute")

}

Scala类型是在编译时定义的,在运行时是静态的,因此“动态创建[]类型”是不可启动的。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM