考虑以下类型定义:
trait LiftF[F[_], G[_]] {
def liftF[A](fa: F[A]): G[A]
}
Run Code Online (Sandbox Code Playgroud)
在上下文边界中提供对此类隐式的要求时(使用种类投影仪插件),我们必须这样编写:
def func[A, G[_], F[_]: LiftF[?[_], G]](a: F[A]): G[A]
Run Code Online (Sandbox Code Playgroud)
我想摆脱这一?[_]部分,所以我最初的猜测是编写一个To[G[_]]返回的类型,LiftF[?[_], G]以将上述函数定义转换为
def func[A, G[_], F[_]: LiftF.To[G]](a: F[A]): G[A]
Run Code Online (Sandbox Code Playgroud)
但是,在将类型To定义写为
type To[G[_]] = LiftF[?[_], G]
Run Code Online (Sandbox Code Playgroud)
我收到以下编译错误:
Error:(17, 20) type ?$ takes type parameters
type To[G[_]] = LiftF[?[_], G]
Run Code Online (Sandbox Code Playgroud)
尝试使用存在性类型重写它会产生以下类型定义:
type To[G[_]] = LiftF[F, G] forSome { type F[X] }
Run Code Online (Sandbox Code Playgroud)
这可以很好地编译,但是,毫无疑问,它不能应用于其他类型参数,因此无法实现所需的函数定义。
我设法通过受aux模式启发的代码实现了“部分应用程序”部分:
trait To[G[_]] {
type From[F[_]] = LiftF[F, G]
}
Run Code Online (Sandbox Code Playgroud)
可悲的是,这给我留下了比原始语法差的语法:
def func[A, …Run Code Online (Sandbox Code Playgroud) types scala partial-application higher-kinded-types kind-projector
在 Scala 反射中,通常可以使用 TypeCreator 从 Type 构造 TypeTag:
object TypeUtils {
import ScalaReflection.universe._
def createTypeTag[T](
tpe: Type,
mirror: reflect.api.Mirror[reflect.runtime.universe.type]
): TypeTag[T] = {
TypeTag.apply(
mirror,
NaiveTypeCreator(tpe)
)
}
case class NaiveTypeCreator(tpe: Type) extends reflect.api.TypeCreator {
def apply[U <: reflect.api.Universe with Singleton](
m: reflect.api.Mirror[U]): U#Type = {
// assert(m eq mirror, s"TypeTag[$tpe] defined in $mirror cannot be migrated to $m.")
tpe.asInstanceOf[U#Type]
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,事实证明 的输出createTypeTag不可序列化,这与编译时推理创建的 typeTag 不同:
import java.io.{ByteArrayOutputStream, ObjectOutputStream}
import org.apache.spark.sql.catalyst.ScalaReflection
import org.scalatest.FunSpec
class TypeTagFromType extends FunSpec { …Run Code Online (Sandbox Code Playgroud) 这是我的代码的简化版本。
我怎样才能避免打电话asInstanceOf(因为这是设计不佳的解决方案的味道)?
sealed trait Location
final case class Single(bucket: String) extends Location
final case class Multi(buckets: Seq[String]) extends Location
@SuppressWarnings(Array("org.wartremover.warts.AsInstanceOf"))
class Log[L <: Location](location: L, path: String) { // I prefer composition over inheritance
// I don't want to pass location to this method because it's a property of the object
// It's a separated function because there is another caller
private def getSinglePath()(implicit ev: L <:< Single): String = s"fs://${location.bucket}/$path"
def getPaths(): Seq[String] =
location match { …Run Code Online (Sandbox Code Playgroud) 我有一个Foo带有两个参数的类,我正在尝试为Foo编写一个Functor实例,并修复了第一个参数,如下所示:
object Scratchpad {
trait Functor[F[_]] {
def fmap[A, B](f: A => B): F[A] => F[B]
}
case class Foo[X, Y](value: Y)
implicit def fooInstances[X]: Functor[Foo[X, _]] =
new Functor[Foo[X, _]] {
def fmap[A, B](f: A => B): Foo[X, A] => Foo[X, B] =
foo => Foo[X, B](f(foo.value))
}
}
Run Code Online (Sandbox Code Playgroud)
但上面的代码无法编译,生成以下错误:
Error:(9, 41) Scratchpad.Foo[X, _] takes no type parameters, expected: one
implicit def fooInstances[X]: Functor[Foo[X, _]] =
Run Code Online (Sandbox Code Playgroud)
我知道Scalaz用它们的\/类型做了类似的事情,但是对它们的源代码的检查显示出一个奇怪的?,它不能为我编译:
implicit def DisjunctionInstances1[L]: Traverse[L \/ ?] …Run Code Online (Sandbox Code Playgroud) 说我有一个类型
trait Mode[T]
trait MyType[T, M <: Mode[T]]
Run Code Online (Sandbox Code Playgroud)
这编译
val t: MyType[_, _] = ???
t
Run Code Online (Sandbox Code Playgroud)
但不是这个
val t: MyType[_, _] = ???
"some_string" -> t
Run Code Online (Sandbox Code Playgroud)
错误说的是 type arguments [_$0,_$1] do not conform to trait MyType's type parameter bounds
所以我的问题是为什么这不会在元组创建时编译?
在帕斯卡三角形中,三角形边上的数字都是1,三角形内部的每个数字都是它上面两个数字的和。帕斯卡三角形示例如下所示。
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
Run Code Online (Sandbox Code Playgroud)
我编写了一个程序,使用以下技术计算帕斯卡三角形的元素。
/**
* Can I make it tail recursive???
*
* @param c column
* @param r row
* @return
*/
def pascalTriangle(c: Int, r: Int): Int = {
if (c == 0 || (c == r)) 1
else
pascalTriangle(c-1, r-1) + pascalTriangle(c, r - 1)
}
Run Code Online (Sandbox Code Playgroud)
所以,例如如果
i/p: pascalTriangle(0,2)
o/p: 1.
i/p: pascalTriangle(1,3)
o/p: 3.
Run Code Online (Sandbox Code Playgroud)
上面的程序是正确的,并给出了预期的正确输出。我的问题是,是否可以编写上述算法的尾递归版本?如何?
// Start writing your ScalaFiddle code here
sealed trait DSL[A]{
// def run(): A ={
// this match {
// case GetLength(something) =>
// something.length
// case ShowResult(number) =>
// s"the length is $number"
// }
// }
}
case class GetLength(something: String) extends DSL[Int]
case class ShowResult(number: Int) extends DSL[String]
def run[A](fa:DSL[A]): A ={
fa match {
case GetLength(something) =>
something.length
case ShowResult(number) =>
s"the length is $number"
}
}
val dslGetLength = GetLength("123456789")
val length = run(dslGetLength)
val …Run Code Online (Sandbox Code Playgroud) 如何TypeRepr在更高级的类型上正确地进行模式匹配?存在成功匹配类,但是当我尝试使用类型时,出现编译器错误unreducible application of higher-kinded type writetype.Foo to wildcard arguments
import scala.quoted.*
type Foo[X]
class Bar[X]
inline def writeType[T]: String = ${writeTypeImpl[T]}
def writeTypeImpl[T](using Type[T], Quotes): Expr[String] =
import quotes.reflect.*
val tpe = TypeRepr.of[T]
val s = tpe.asType match
//case '[Foo[?]] => "FooSuccess"
case '[Bar[?]] => "BarSuccess"
case _ => "Fail"
Expr(s)
Run Code Online (Sandbox Code Playgroud) 我正在学习 Scala 3,我对匹配类型和文字类型很感兴趣。
我想编写一个函数,它采用几种文字类型之一,并返回特定类型作为传入文字类型的函数。
这是我正在尝试做的一个相当简单的例子:
type TestMatchType[T] = T match
case "String1" => Int
case "String2" => String
def testMatchType[T](input: T): TestMatchType[T] =
input match
case "String1": "String1" => 1
case "String2": "String2" => "Two"
val string1Output: Int = testMatchType("String1")
Run Code Online (Sandbox Code Playgroud)
用言语来说:
testMatchType它接受一个参数,该参数的类型要么是文字类型"String1",要么是文字类型"String2"。如果传递了具有类型的参数"String1",则该函数应该返回一个Int。如果传递了具有类型的参数"String2",该函数应该返回一个String。如果传递的参数的类型不是这些类型文字之一,则会产生编译时错误。但是,当我尝试编译上面的代码时,出现以下错误:
1 |val string1Output: Int = testMatchType("String1")
| ^^^^^^^^^^^^^^^^^^^^^^^^
| Found: TestMatchType[String]
| Required: Int
|
| Note: a match type could not be …Run Code Online (Sandbox Code Playgroud) 这是一个简单的例子:
trait Proposition[T] {
type Repr = T
}
trait Scope {
type OUT
type Consequent = Proposition[_ <: OUT]
abstract class Proof[-I, +P <: Consequent] {
final def instanceFor(v: I): P#Repr = ???
final def apply(v: I): P#Repr = instanceFor(v)
}
}
Run Code Online (Sandbox Code Playgroud)
这给出了编译错误:
[Error] ....scala:44: type mismatch;
found : _$1(in type Consequent)
required: (some other)_$1(in type Consequent)
Run Code Online (Sandbox Code Playgroud)
这是从哪里来(some other)的?是否是由明确的类型选择规则引起的编译器错误(理论上应该在scala 3中解决)?
更新 1抱歉,我刚刚意识到P#Repr不应该称为类型选择,它应该仅指val p: P;p.Repr,现在它增加了更多混乱,因为:
我什至不知道这个语法的名字,但我一直使用它很长一段时间
它甚至没有在 DOT 演算中定义。所以 scala 3 支持值得怀疑
scala existential-type path-dependent-type dependent-type scala-2.13
scala ×10
scala-3 ×2
typeclass ×2
types ×2
algorithm ×1
casting ×1
generics ×1
implicit ×1
match-types ×1
recursion ×1
reflection ×1
scala-2.13 ×1
scala-macros ×1
scalaz ×1