문제

다음과 같은 것이 있다고 가정합니다.

trait Cursor {
}

trait Column[T] {
   def read(cusor: Cursor): T
}

trait ColumnReader {
   def readColumns(columns: Product[Column[_]], cursor: Cursor): Iterable[Any] = {
       for (column <- columns) yield column.read(cursor)
   }
}
.

readColumns() API의 문제점은 제가 유형 정보를 잃는 것입니다. 즉,이 경우 :

object columnString extends Column[String] {
   def read(cursor: Cursor): String = ...
}

object columnInt extends Column[Int] {
   def read(cursor: Cursor): Int = ...
}
.

new ColumnReader().readColumns((columnString, columnInt))와 같은 표현식은 Iterable[Any]를 반환합니다.Tuple2[String, Int]처럼 입력 한 것을 반환하고 싶지만 방법을 모릅니다.나는 컴파일러에 유용한 유형의 정보를 잃는다.

어쩌면 "Nofollow"> 엉성한 와 같은 도서관이 유용 할 수 있습니다.

Scala는 이와 같은 문제를 다루는 도구가 있습니다.

아이디어가 있습니까?

도움이 되었습니까?

해결책

셰이프가없는 HList

를 사용하는 예
class Cursor

trait Column[T] {
  def read(cusor: Cursor): T
}

class CursorContainer(cursor: Cursor) {
  object mapper extends Poly1 {
    implicit def any[T] = at[Column[T]](_.read(cursor))
  }
}

class ColumnReader {

  def readColumns[T <: HList](columns: T, cursor: CursorContainer)(
    implicit m:Mapper[cursor.mapper.type, T]) = columns.map(cursor.mapper)
}

val columnString = new Column[String] {
  def read(cursor: Cursor): String = ???
}

val columnInt = new Column[Int] {
  def read(cursor: Cursor): Int = ???
}

val reader = new ColumnReader
val cursor =  new CursorContainer(new Cursor)
val result: String :: Int :: HNil =
  reader.readColumns(columnString :: columnInt :: HNil, cursor)
.

다른 팁

타입 매개 변수를 취할 수있는 컨테이너를 사용하지 않는 경우 예를 들어, 예를 들어,서열 또는 목록?

trait Cursor {
}

trait Column[T] {
   def read(cusor: Cursor): T
}

trait ColumnReader[T] {
   def readColumns(columns: Seq[Column[T]], cursor: Cursor): Iterable[T] = {
       for (column <- columns) yield column.read(cursor)
   }
}
.

엉덩이가없는 hlist가 필요합니다

열의 수가 제한되어있는 경우에도 적용을 사용할 수도 있습니다.

trait Column[T] {
  def read(c: Cursor) : Id[T]
}
object columnString extends Column[String]
{
  override def read(c: Cursor): Id[String] = "hello"
}

object columnInt extends Column[Int] {
  override def read(c: Cursor): Id[Int] = 3
}

type ColumnReader[T] = Reader[Cursor, T]

val readSpreadSheet1 : ColumnReader[(Int, String)] = Reader {
  c =>
    (columnInt.read(c) |@| columnString.read(c)) { (_,_)}
}

readSpreadSheet1(c)
.

가 발생합니다 :

res1: scalaz.Id.Id[(Int, String)] = (3,hello)
.

나는 또한 작은 독자 정의에 던져 졌으므로 행을 읽을 때 커서의 인스턴스를 통과시키는 것에 관심을 갖지 않아도됩니다.단점에서는 미리 열의 유형을 알아야하지만 HLIST를 사용할 때 이것도 사실 일 것이라고 생각합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top