Search code examples
scalashapelesssingleton-type

Shapeless narrow type loss


In the following example

import shapeless._
import shapeless.syntax.singleton._

val concat = "right".narrow

def extract[s <: String](x: s)(implicit witness: Witness.Aux[s]): String = witness.value

extract(concat)

I'm getting an error

Error: could not find implicit value for parameter witness:shapeless.Witness.Aux[String("right")]

The thing I'm trying to do is a type level DSL which is heavily relied on singleton types.

Since singleton typed literals are badly supported outside typelevel's fork, I was hoping to develop value-based DSL in addition to type literals, and preservation of usable singleton types in value types is critical for this task.
So I'm looking for any workaround which allows me to extract singleton string witness from value's type later.

Edit

operations using .witness instead of .narrow are working perfectly, but I'm still looking for solution for pure types without Witness wrapping


Solution

  • This is a failure of type inference ... you'll find that,

    extract[concat.type](concat)
    

    will work as you expect.

    That's not particularly helpful, as I imagine you want to infer the singleton type from the value argument to extract. shapeless provides an implicit conversion to Witness types, so the following might work in your context,

    def extract(witness: Witness.Lt[String]): String = witness.value
    

    This will accept both literal Strings and narrowed values.