Firstly, the follow code works as excepted:
(All codes are in https://scastie.scala-lang.org/A0245eqTRqafqh8m9j1nxg)
scala> type Elem[T] = T match
| case String => Char
| case Seq[e] => e
| case Array[e] => e
|
|
| extension[Coll](coll: Coll)
| def insert0(elem: Elem[Coll]): Coll = ???
|
| Array(1, 2).insert0
val res0: Int => Array[Int] = Lambda$1818/0x0000000800946040@797ee1a9
Now I want to implement a format operator %
like python’s, plus with compile time type safe:
import scala.compiletime.ops.string.*
type Args[Fmt <: String] <: Tuple = Length[Fmt] match
case 0 | 1 => EmptyTuple
case _ => Substring[Fmt, 0, 2] match
case "%%" => Args[Substring[Fmt, 2, Length[Fmt]]]
case "%s" => String *: Args[Substring[Fmt, 2, Length[Fmt]]]
case "%d" => Int *: Args[Substring[Fmt, 2, Length[Fmt]]]
case "%f" => Double *: Args[Substring[Fmt, 2, Length[Fmt]]]
case _ => Args[Substring[Fmt, 1, Length[Fmt]]]
extension[Fmt <: String & Singleton](fmt: Fmt)
def % (args: Args[Fmt]): String =
val itr = args.productIterator
def format(f: String): String = f match
case "" => ""
case s"%%$tail" => "%" + format(tail)
case s"%s$tail" => itr.next.toString + format(tail)
case s"%d$tail" => itr.next.toString + format(tail)
case s"%f$tail" => itr.next.toString + format(tail)
case _ => f.take(1) + format(f.drop(1))
format(fmt)
I would expect the following f1
as a function instance of type ((Int, Int, String)) => String
, but it does not. Why?
scala> val s1 = "%d + %d = %s" % (1, 2, "three")
val s1: String = 1 + 2 = three
scala> val f1 = "%d + %d = %s" % _
-- [E081] Type Error: --------------------------------------------------------------------------------------------------------------------------------------------------
1 |val f1 = "%d + %d = %s" % _
| ^
| Missing parameter type
|
| I could not infer the type of the parameter _$1 of expanded function:
| _$1 => "%d + %d = %s" % _$1.
1 error found