我想在包装函数中定义隐式值,并将其提供给内部函数使用,到目前为止,我设法通过从包装器传递隐式变量来做到这一点:
case class B()
trait Helper {
def withImplicit[A]()(block: => A): A = {
implicit val b: B = B()
block
}
}
class Test extends Helper {
def useImplicit()(implicit b: B): Unit = {...}
def test = {
withImplicit() { implicit b: B =>
useImplicit()
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否有可能避免implicit b: B =>,并implicit val b: B = B()提供给内部功能块?
我有一个下面的类,它使用协方差注释和另一个类型参数作为其方法,该类类型参数是下界
class MyQueue[+T]{
def add[U >: T](arg:U):Unit= {
println("Arg value :"+ arg)
}
}
Run Code Online (Sandbox Code Playgroud)
鉴于上面的代码,我不明白为什么下面的行执行成功。根据我对下限的理解,方法“add”应该只接受 Int 类型或其超类型的值。
val q1:MyQueue[Int] = new MyQueue[Int]
q1.add("string")
Run Code Online (Sandbox Code Playgroud)
但是,如果我们如下显式指定类型参数,它会给出预期的编译错误(String 不符合方法 add 的类型参数界限)
q1.add[String]("string")
Run Code Online (Sandbox Code Playgroud) 在 scala 语言中,隐式解析通常在编译时完成,有时会抛出混淆的错误信息,此类错误的一个著名例子是当 shapeless Generic 抛出错误信息时,如:
error: could not find implicit value for parameter encoder: CsvEncoder[Foo]
Run Code Online (Sandbox Code Playgroud)
(详见https://books.underscore.io/shapeless-guide/shapeless-guide.html)
这个问题的一个解决方案是在运行时运行隐式解析算法(内部应该是图查询算法),这至少有两个好处:
调试工具可用于逐步重现解决过程,因此即使错误信息和文档不完整,也很容易发现错误。
在许多情况下,类型信息可能无法在编译时确定(例如,类型取决于控制流)。如果隐式转换不能延迟到运行时阶段,那么定义隐式转换的许多好处将无效。
所以我的问题是,Scala 2.x 或 Dotty 中是否存在此功能?还是在路线图上?
非常感谢您的意见。
鉴于:
abstract class Databases[F[_]]
Run Code Online (Sandbox Code Playgroud)
我怎样才能使这个特性起作用:
// Marker trait signalling the database plugin supports StaticRoles
trait StaticRoles { this: Databases[_] => }
Run Code Online (Sandbox Code Playgroud)
我想确保StaticRoles只混合在也扩展的类中Databases,但是我不关心类型参数的具体值F。
代码返回:
error: _$1 takes no type parameters, expected: one
Run Code Online (Sandbox Code Playgroud)
这是公平的,但是它返回相同的错误:
trait StaticRoles { this: Databases[_[_]] => }
Run Code Online (Sandbox Code Playgroud)
我也试过:
trait StaticRoles { this: Databases[({type T[X[_]]})#T] => }
Run Code Online (Sandbox Code Playgroud)
这给出了错误:
error: kinds of the type arguments (AnyRef{type T[X[_]]}#T) do not conform to the expected kinds of the type parameters (type F) in class Databases.
AnyRef{type …Run Code Online (Sandbox Code Playgroud) 请看下面的类型参数子句[F[_] <: Int]中
def h[F[_] <: Int] = ???
Run Code Online (Sandbox Code Playgroud)
其中类型构造函数F受正确类型的限制Int。现在,这两个h[List]和h[Int]是非法的
scala> def h[F[_] <: Int] = ???
|
def h[F[_] <: Int]: Nothing
scala> h[List]
^
error: type arguments [List] do not conform to method h's type parameter bounds [F[_] <: Int]
scala> h[Int]
^
error: Int takes no type parameters, expected: 1
Run Code Online (Sandbox Code Playgroud)
那么为什么是[F[_] <: Int]合法的呢?
generics scala type-constraints higher-kinded-types type-constructor
我有一个带有 2 个类型参数的案例类
case class Relation[T <: Model, RT] (model: T)
Run Code Online (Sandbox Code Playgroud)
类型 T 显然是一种类属性“模型”。类型 RT 可以与 T 相同,也可以是 List[T](取决于我们创建 OneToOne 或 OneToMany 的关系类型)。那么我如何限制 RT,它不允许传递除 T 或 List[T] 之外的其他内容。
PS 我正在阅读有关covariance和contravariance 的内容,但不太了解。它适用于我的情况吗?如果是,请您举例说明。如果没有 - 那么请展示其他工具来达到它。我什至无法理解 T 和 List[T] 是如何相互关联的?T <: List[T] 或 List[T] <: T?
提前致谢
我将通过https://www.scala-exercises.org/获取Cats。我想我明白是什么意思了Apply.ap。但我看不到它有任何用途。
有什么区别:
Apply[Option].map(Some(1))(intToString)
Run Code Online (Sandbox Code Playgroud)
和
Apply[Option].ap(Some(intToString))(Some(1))
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下或指出更多解释吗?
假设我有两个类Person和Business,它们由特质 扩展Entity。
trait Entity
case class Person(name: String) extends Entity
case class Business(id: String) extends Entity
Run Code Online (Sandbox Code Playgroud)
假设我无法更改Entity,Person并且Business(它们位于不同的文件中并且不能更改),我如何定义一个函数,例如 a ,根据实体printEntity打印字段name或?id例如,给定Person和的实例Business,我该如何做这样的事情:
object Main extends App {
val person1: Person = Person("Aaaa Bbbb")
val business1: Business = Business("0001")
// How can I do something like this?
person1.printEntity // would call a function that executes println(id)
business1.printEntity // would call a function …Run Code Online (Sandbox Code Playgroud) 从 2017 年有关 nanopass 编译器的演讲 ( https://github.com/sellout/recursion-scheme-talk/blob/master/nanopass-compiler-talk.org ) 中,我找到了下面的代码片段。在这段代码片段中,我看到两个通用约束,我已经上下搜索以理解它们,但无法找到有关它们的任何信息。我希望了解的是:
\nfinal case class Let[A](bindings: List[(String, A)], body: A)\nfinal case class If[A](test: A, consequent: A, alt: A)\n\ndef expandLet[Lambda :<: F]: Fix[Let :+: F] => Fix[F] =\n _.unFix match {\n case Let(bindings, body) =>\n bindings.unzip((names, exprs) =>\n Fix(App(Fix(Lam(names, expandLet(body)).inject),\n exprs.map(expandLet)).inject))\n // and don\xe2\x80\x99t forget the other cases\n }\n\ndef expandIf[Lambda :<: F]: Fix[If :+: F] => Fix[F] =\n _.unFix match {\n case If(test, …Run Code Online (Sandbox Code Playgroud) scala higher-kinded-types scalaz scala-cats recursion-schemes
不确定正确的术语是否是“分配财产”,但我记得在学校学过这个,所以这里是我想做的一个例子:
鉴于:
type MyHList = (A :+: B :+: C :+: CNil) :: (Foo :+: Bar :+: CNil) :: HNil
Run Code Online (Sandbox Code Playgroud)
Shapeless 中是否有任何内置类型类可以解决这个问题:
type Out = (A, Foo) :+: (A, Bar) :+: (B, Foo) :+: (B, Bar) :+: (C, Foo) :+: (C, Bar) :+: CNil
Run Code Online (Sandbox Code Playgroud)
?
谢谢
scala ×10
implicit ×3
covariance ×2
dotty ×2
scala-cats ×2
applicative ×1
class ×1
coproduct ×1
functor ×1
generics ×1
hlist ×1
scalameta ×1
scalaz ×1
self-type ×1
shapeless ×1
type-bounds ×1
union-types ×1