Applying a function to elements of an HList safely

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Applying a function to elements of an HList safely

Hugo Ferreira
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/

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Applying a function to elements of an HList safely

Jasper-M
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:
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. <a href="https://github.com/dragisak/type-level/blob/master/src/main/scala/com/dragisak/typelevel/HList.scala" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdragisak%2Ftype-level%2Fblob%2Fmaster%2Fsrc%2Fmain%2Fscala%2Fcom%2Fdragisak%2Ftypelevel%2FHList.scala\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHV0zFiB7QRLN6PehVx1sPbog69kw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdragisak%2Ftype-level%2Fblob%2Fmaster%2Fsrc%2Fmain%2Fscala%2Fcom%2Fdragisak%2Ftypelevel%2FHList.scala\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHV0zFiB7QRLN6PehVx1sPbog69kw&#39;;return true;">https://github.com/dragisak/type-level/blob/master/src/main/scala/com/dragisak/typelevel/HList.scala
2. <a href="https://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fapocalisp.wordpress.com%2F2010%2F06%2F08%2Ftype-level-programming-in-scala%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHHZhlZGkqQq7qo-VFuAqAQJ5hs5g&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fapocalisp.wordpress.com%2F2010%2F06%2F08%2Ftype-level-programming-in-scala%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHHZhlZGkqQq7qo-VFuAqAQJ5hs5g&#39;;return true;">https://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/
3. <a href="https://github.com/milessabin/shapeless/issues/73" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fmilessabin%2Fshapeless%2Fissues%2F73\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEsONIUPk8_n_AA1rFXttexEYV_hw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fmilessabin%2Fshapeless%2Fissues%2F73\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEsONIUPk8_n_AA1rFXttexEYV_hw&#39;;return true;">https://github.com/milessabin/shapeless/issues/73
4. <a href="https://xuwei-k.github.io/shapeless-sxr/shapeless-2.10-2.0.0-M1/polyntraits.scala.html" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fxuwei-k.github.io%2Fshapeless-sxr%2Fshapeless-2.10-2.0.0-M1%2Fpolyntraits.scala.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVEXnWmGPGPRWA6teMTsGWup0K6A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fxuwei-k.github.io%2Fshapeless-sxr%2Fshapeless-2.10-2.0.0-M1%2Fpolyntraits.scala.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVEXnWmGPGPRWA6teMTsGWup0K6A&#39;;return true;">https://xuwei-k.github.io/shapeless-sxr/shapeless-2.10-2.0.0-M1/polyntraits.scala.html
5. <a href="http://www.hyperlambda.com/posts/hlist-map-in-scala/" target="_blank" rel="nofollow" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.hyperlambda.com%2Fposts%2Fhlist-map-in-scala%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHZtC4dbIvFWqzLjH4V7HeokfBGPg&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.hyperlambda.com%2Fposts%2Fhlist-map-in-scala%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHZtC4dbIvFWqzLjH4V7HeokfBGPg&#39;;return true;">http://www.hyperlambda.com/posts/hlist-map-in-scala/

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Applying a function to elements of an HList safely

Hugo Ferreira
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.



On Wednesday, 11 January 2017 13:10:59 UTC, Jasper-M wrote:
Hi,

You may want to look at <a href="https://github.com/underscoreio/shapeless-guide" target="_blank" rel="nofollow" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Funderscoreio%2Fshapeless-guide\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHt8Q6C7XkcAPOnBjZqYheZYEPxxQ&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Funderscoreio%2Fshapeless-guide\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHt8Q6C7XkcAPOnBjZqYheZYEPxxQ&#39;;return true;">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:
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. <a href="https://github.com/dragisak/type-level/blob/master/src/main/scala/com/dragisak/typelevel/HList.scala" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdragisak%2Ftype-level%2Fblob%2Fmaster%2Fsrc%2Fmain%2Fscala%2Fcom%2Fdragisak%2Ftypelevel%2FHList.scala\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHV0zFiB7QRLN6PehVx1sPbog69kw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fdragisak%2Ftype-level%2Fblob%2Fmaster%2Fsrc%2Fmain%2Fscala%2Fcom%2Fdragisak%2Ftypelevel%2FHList.scala\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHV0zFiB7QRLN6PehVx1sPbog69kw&#39;;return true;">https://github.com/dragisak/type-level/blob/master/src/main/scala/com/dragisak/typelevel/HList.scala
2. <a href="https://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fapocalisp.wordpress.com%2F2010%2F06%2F08%2Ftype-level-programming-in-scala%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHHZhlZGkqQq7qo-VFuAqAQJ5hs5g&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fapocalisp.wordpress.com%2F2010%2F06%2F08%2Ftype-level-programming-in-scala%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHHZhlZGkqQq7qo-VFuAqAQJ5hs5g&#39;;return true;">https://apocalisp.wordpress.com/2010/06/08/type-level-programming-in-scala/
3. <a href="https://github.com/milessabin/shapeless/issues/73" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fmilessabin%2Fshapeless%2Fissues%2F73\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEsONIUPk8_n_AA1rFXttexEYV_hw&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fgithub.com%2Fmilessabin%2Fshapeless%2Fissues%2F73\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNEsONIUPk8_n_AA1rFXttexEYV_hw&#39;;return true;">https://github.com/milessabin/shapeless/issues/73
4. <a href="https://xuwei-k.github.io/shapeless-sxr/shapeless-2.10-2.0.0-M1/polyntraits.scala.html" rel="nofollow" target="_blank" onmousedown="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fxuwei-k.github.io%2Fshapeless-sxr%2Fshapeless-2.10-2.0.0-M1%2Fpolyntraits.scala.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVEXnWmGPGPRWA6teMTsGWup0K6A&#39;;return true;" onclick="this.href=&#39;https://www.google.com/url?q\x3dhttps%3A%2F%2Fxuwei-k.github.io%2Fshapeless-sxr%2Fshapeless-2.10-2.0.0-M1%2Fpolyntraits.scala.html\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNFVEXnWmGPGPRWA6teMTsGWup0K6A&#39;;return true;">https://xuwei-k.github.io/shapeless-sxr/shapeless-2.10-2.0.0-M1/polyntraits.scala.html
5. <a href="http://www.hyperlambda.com/posts/hlist-map-in-scala/" rel="nofollow" target="_blank" onmousedown="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.hyperlambda.com%2Fposts%2Fhlist-map-in-scala%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHZtC4dbIvFWqzLjH4V7HeokfBGPg&#39;;return true;" onclick="this.href=&#39;http://www.google.com/url?q\x3dhttp%3A%2F%2Fwww.hyperlambda.com%2Fposts%2Fhlist-map-in-scala%2F\x26sa\x3dD\x26sntz\x3d1\x26usg\x3dAFQjCNHZtC4dbIvFWqzLjH4V7HeokfBGPg&#39;;return true;">http://www.hyperlambda.com/posts/hlist-map-in-scala/

--
You received this message because you are subscribed to the Google Groups "scala-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [hidden email].
For more options, visit https://groups.google.com/d/optout.
Loading...