小编Dmy*_*tin的帖子

Scala中的部分应用的lambda类型与投影仪

考虑以下类型定义:

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

6
推荐指数
1
解决办法
118
查看次数

在 Scala 中,如何从可序列化的类型创建 TypeTag?

在 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)

reflection types scala scala-reflect

6
推荐指数
1
解决办法
181
查看次数

如何避免在 Scala 中调用 asInstanceOf

这是我的代码的简化版本。

我怎样才能避免打电话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)

casting scala implicit pattern-matching typeclass

6
推荐指数
1
解决办法
128
查看次数

Scala中具有两个参数的类型构造函数的函数实例

我有一个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)

scala typeclass scalaz kind-projector

5
推荐指数
2
解决办法
371
查看次数

在Scala中创建元组时键入绑定错误

说我有一个类型

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

所以我的问题是为什么这不会在元组创建时编译?

scala existential-type

5
推荐指数
1
解决办法
85
查看次数

帕斯卡三角形 Scala:使用尾递归方法计算帕斯卡三角形的元素

在帕斯卡三角形中,三角形边上的数字都是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)

上面的程序是正确的,并给出了预期的正确输出。我的问题是,是否可以编写上述算法的尾递归版本?如何?

algorithm recursion scala tail-recursion

5
推荐指数
1
解决办法
5655
查看次数

在这种情况下,scala 的类型检查如何工作?

// 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)

generics scala type-inference pattern-matching

5
推荐指数
2
解决办法
136
查看次数

Scala 3 TypeRepr 匹配更高种类的类型

如何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 scala-macros scala-3

5
推荐指数
1
解决办法
475
查看次数

Scala 3“无法完全减少匹配类型”与文字类型

我正在学习 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)

scala singleton-type scala-3 match-types

5
推荐指数
1
解决办法
494
查看次数

当使用scala路径依赖类型作为函数共域时,为什么无法为该函数添加别名?

这是一个简单的例子:

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

5
推荐指数
1
解决办法
125
查看次数