Applying a function to elements of an HList safely

41 views
Skip to first unread message

Hugo Ferreira

unread,
Jan 11, 2017, 7:00:38 AM1/11/17
to scala-user
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.scala
2. https://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/
3. https://github.com/milessabin/shapeless/issues/73
4. https://xuwei-k.github.io/shapeless-sxr/shapeless-2.10-2.0.0-M1/polyntraits.scala.html
5. http://www.hyperlambda.com/posts/hlist-map-in-scala/

Jasper-M

unread,
Jan 11, 2017, 8:10:59 AM1/11/17
to scala-user
Hi,

You may want to look at https://github.com/underscoreio/shapeless-guide. Especially chapter 7.

Kind regards,
Jasper

Op woensdag 11 januari 2017 13:00:38 UTC+1 schreef Hugo Ferreira:

Hugo Ferreira

unread,
Jan 12, 2017, 11:24:51 AM1/12/17
to scala-user
Hi Jasper,

Appreciate the link. I took a look at chapter 7, which gave me a few ideas. But short of looking at
and understanding the code means I will have to work at this as best as I can bit by bit.

I have a question concerning this post, but I will start a new threads with more specific questions.

Thanks,
Hugo F.
Reply all
Reply to author
Forward
0 new messages