Search code examples
scalashapeless

Providing additional arguments to map on HList


I would like to do something like this:

def run(subjects: List[Subject]) = {
  val configs = compute()
  subjects.map(s => configs.map(c => test(s,c)))
  // or flatMap, I don't really care at this point
}

In my use case, subjects are actually Subject[T] and I need a typesafe version of T in the result. So I have:

def run[L <: HList](subjects: L)(implicit mapper: Mapper[testFun.type, L]) = {
  val configs = compute()
  subjects.map(testFun)
}

However, now I am unable to pass in the configurations to testFun which, according to this post, needs to have a singleton type.

An option would be to do:

val cfgHL = HList.fill(subjects.length)(configs)
(subjects zip cfgHL).map(testFun)

But HList currently does not have a fill operation. Any hints?


Solution

  • You can use mapConst to accomplish the same thing as fill. If we have the following:

    val xs = 1 :: 'a :: 'a' :: HNil
    

    We can write:

    scala> xs.zip(xs mapConst "x") == (1, "x") :: ('a, "x") :: ('a', "x") :: HNil
    res0: Boolean = true
    

    Note that there are other ways to tackle the problem of partially applying (higher-rank) polymorphic functions and then mapping with them—see for example my answer here. Something like that is likely to be overkill for your use case, though.