Hello,
I have am trying to implement a very simple (bare-bones) HList.
I have studied and taken the code from at least 2 sources [1,2].
So here is what I came up with:
import scala.language.higherKinds
sealed trait HList {
type Prepend[A] <: HList
type Append[L<:HList] <: HList
def ::[U](v: U): Prepend[U]
def prepend[A](a: A): Prepend[A]
def append[ L <: HList ](l: L): Append[L]
}
final case class HCons[ H, T <: HList ](head: H, tail: T) extends HList {
type Prepend[A] = HCons[A,HCons[H,T]]
type Append[ L <: HList ] = HCons[ H, T#Append[ L ] ]
def ::[U](v: U): Prepend[U] = HCons(v, this)
def prepend[A](a: A): Prepend[A] = HCons(a, this)
def append[L <: HList](l: L): Append[L] = HCons(head, tail.append( l ))
}
case object HNil extends HList {
type Prepend[A] = HCons[A, HNil.type]
type Append[L <: HList] = L
def ::[T](v: T): Prepend[T] = HCons(v, this) // No need to type explicitly, same as prepend
def prepend[A](a: A): Prepend[A] = HCons(a, this)
def append[L <: HList](l: L): Append[L] = l
}
object HList {
type ::[H,T<:HList] = HCons[H,T]
val :: = HCons // alias for pattern matching
}
Now I would like to have a means of mapping a function to each and every element of the HList.
For example:
def doF[A, B](list: HList, acc: HList, f : A => B): HList = {
list match {
case HNil => acc
case h :: t =>
println( h )
val nh = f(h)
genCartesian( t, nh :: acc )
}
}
When I compile this I get the following error:
HList.scala:195: type mismatch;
[error] found : h.type (with underlying type Any)
[error] required: A
[error] val nh = f(h)
^
I understand why the type Any, however I don't know how to apply a function to the element based on its type.
Research gave me another 3 references [3,4,5]. The references [3,4] use scalz's HList. I would like to avoid
the use of this code because I want something very simple and easy to maintain. Nevertheless it shows that it is
possible. However when I look at the code, I feel like an "ass looking at a palace". Too many moving parts.
So for several days I have been trying to implement a mapper that can be be used implicitly. I took
inspiration from [5]. I have a very simple mapper hat works on a standard List however this is far from what I
want.
Can anyone point me to material or explain how I may implement something like scalaz's Poly1?
Tall order, I know, but I am hopping their is a simple solution.
TIA.
1.
https://github.com/dragisak/type-level/blob/master/src/main/scala/com/dragisak/typelevel/HList.scala2.
https://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/ 3.
https://github.com/milessabin/shapeless/issues/734.
https://xuwei-k.github.io/shapeless-sxr/shapeless-2.10-2.0.0-M1/polyntraits.scala.html5.
http://www.hyperlambda.com/posts/hlist-map-in-scala/