相关疑难解决方法(0)

带有子类型的scala中的联合类型:A | B <:A | B | C.

我想要一个A|B类型作为子类型A|B|C.这可能在Scala中编码吗?如果有,怎么样?

我希望我可以在implicitly[¬¬[IF] <:< T]下面进行编译(原始代码在这里),但事实并非如此.有没有办法修复此代码以允许子类型?

object NUnion{
  type ¬¬[A] = ¬[¬[A]]

  type ¬[A] = A => Nothing
  trait Disj[T] {
    type or[S] = Disj[T with ¬[S]]
    type apply = ¬[T]
  }

  // for convenience
  type disj[T] = { type or[S] = Disj[¬[T]]#or[S] }


  type T = disj[Int]#or[Float]#or[String]#apply
  type IF = disj[Int]#or[Float]#apply
  implicitly[¬¬[Int] <:< T] // works
  // implicitly[¬¬[Double] <:< T] // doesn't work
  // implicitly[¬¬[IF] <:< T] // doesn't work - but it …
Run Code Online (Sandbox Code Playgroud)

scala subtyping union-types

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

具有上限的联合类型

我正在遵循这个问题的接受答案中提出的技术 如何定义"类型分离"(联合类型)?为了支持对方法的多类型参数进行类型检查.

隐含的"证据"

@implicitNotFound(msg="Only String, Array[Byte] and InputStream are supported")
  sealed class Input[T]
  object Input{
    implicit object ByteArrayWitness extends Input[Array[Byte]]
    implicit object StringWitness extends Input[String]
    implicit object InputStreamWitness extends Input[InputStream]
  }
Run Code Online (Sandbox Code Playgroud)

API方法

def foo[T: Input](param: T) =
  param match {
    case x: String => //...
    case x: Array[Byte] => //...
    case x: InputStream => //...
    case _ => throw new UnsupportedOperationException(s"not implemented for type ${param.getClass}")
  }
Run Code Online (Sandbox Code Playgroud)

问题

这个编译

foo("test")
foo(Array[Byte](123.toByte))
Run Code Online (Sandbox Code Playgroud)

但这不是(因为它不具体InputStream)

foo(new ByteArrayInputStream("abc".getBytes("UTF-8")))
Run Code Online (Sandbox Code Playgroud)

我必须将其转换为确切的超类型以使其工作(此编译)

foo(new ByteArrayInputStream("abc".getBytes("UTF-8")).asInstanceOf[InputStream])
Run Code Online (Sandbox Code Playgroud)

有没有办法改变 …

types scala

4
推荐指数
1
解决办法
320
查看次数

是否可以根据Scala中的另一个清单定义清单?

是否可以根据Scala中的另一个清单定义清单?

我几乎不相信这是不可能的,因为Scala Manifest信息不是动态使用的.

这是问题所在.我有一个函数可以返回多种类型的对象(String,Int,List [Int],List [List [String]]等).为了支持这些多种类型,返回类型设置为Any,但是由于要键入擦除,列表,地图等支持的类型信息将丢失.为了恢复一些细节,我返回一个Manifest以及返回类型.

但是,返回的信息可以放在另一个列表或映射中,然后从另一个函数返回.我想更新清单,以包括类型现在是清单定义的先前类型的List或Map这一事实.

这是一些示例代码

def returnWithManifest[T: Manifest](x: T) = (x, manifest[T])

// May return String, Int, List[Int], List[List[String]], ...
def contrivedExample(t: String): (Any, Manifest[_]) = t match {
  case "String" => returnWithManifest("test")
  case "Int" => returnWithManifest(1)
  case "Boolean" => returnWithManifest(true)
  case "List[Int]" => returnWithManifest(List(1,2,3))
  case "List[List[String]]" => 
    returnWithManifest(List(List("a","b"),List("c","d")))
  case _ => returnWithManifest(None)
}

scala> val v1 = contrivedExample("List[Int]")
v1: (Any, Manifest[_]) = (List(1, 2, 3),scala.collection.immutable.List[Int])

scala> val x = v1._1
x: Any = List(1, 2, …
Run Code Online (Sandbox Code Playgroud)

scala manifest

3
推荐指数
2
解决办法
299
查看次数

在Scala中,如何定义在运行时工作的联合类型?

接下来就如何在Scala中定义联合类型形成了这一组优秀的答案.我一直在使用Miles Sabin对Union类型的定义,但仍有一个问题.

如果直到运行时才知道类型,你如何使用这些?例如:

trait inv[-A] {}
type Or[A,B] = {
  type check[X] = (inv[A] with inv[B]) <:< inv[X]
}

case class Foo[A : (Int Or String)#check](a: A)

Foo(1)    // Foo[Int] = Foo(1)
Foo("hi") // Foo[String] = Foo(hi)
Foo(2.0)  // Error!
Run Code Online (Sandbox Code Playgroud)

此示例有效,因为参数A在编译时已知,并且调用Foo(1)实际上正在调用Foo[Int](1).但是,如果A在运行时之前不知道参数,您会怎么做?也许你正在削减包含Foos 的数据的文件,在这种情况下,在Foo读取数据之前不知道类型参数.A在这种情况下,没有简单的方法来设置参数.

我能够提出的最佳解决方案是:

  • 模式匹配您已阅读的数据,然后Foo根据该类型创建不同的数据.在我的情况下,这是不可行的,因为我的case-class实际上包含了几十个union类型,因此有数百种类型的组合来模式匹配.

  • 转换您刚读过的类型(String or Int),因此您只能传递一种类型,在Foo使用它时传递Type Class约束.然后返回Foo[_].这使得Foo用户有责任计算出每个字段的类型(因为它们看起来都是Any类型),但至少在实际使用字段之前它必须知道类型,在这种情况下,模式匹配似乎更容易处理.

第二个解决方案如下所示:

def parseLine: Any // Parses …
Run Code Online (Sandbox Code Playgroud)

functional-programming scala union-types

3
推荐指数
1
解决办法
1212
查看次数

T 和 List[T] 的类型参数边界

我有一个带有 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 我正在阅读有关covariancecontravariance 的内容,但不太了解。它适用于我的情况吗?如果是,请您举例说明。如果没有 - 那么请展示其他工具来达到它。我什至无法理解 T 和 List[T] 是如何相互关联的?T <: List[T] 或 List[T] <: T?

提前致谢

scala covariance union-types

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

Scala联合类型与闭包

我正在尝试在Miles Sabin的博客文章中定义的Scala的联合类型:

http://www.chuusai.com/2011/06/09/scala-union-types-curry-howard/

并在中讨论过

如何定义"类型析取"(联合类型)?

对于那里定义的简单情况,它们工作正常,但我要做的是使用它们在Play Framework中创建一个只接受某些值(String,Boolean,Int,Undefined)的通用JSON解析器,然后成功传递它们.

这是我的代码:

type UpdateType = Option[String] |?| Option[Int] |?| Option[Boolean] |?| Option[List[Int]]

def withValue[T : (UpdateType)#?](request: Request[JsValue])(block: (String, T) => Future[SimpleResult]) = {
  val field = request.body \ ("field")
  val value = request.body \ ("value")
  (field, value) match {
    case (x: JsString, y: JsString) => block(x.value.toString, Some(y.value.toString))
    case (x: JsString, y: JsNumber) => block(x.value.toString, Some(y.value.intValue))
    case (x: JsString, y: JsBoolean) => block(x.value.toString, Some(y.value.booleanValue))
    case (x: JsString, y: JsUndefined) => block(x.value.toString, None)
    case _ => …
Run Code Online (Sandbox Code Playgroud)

scala shapeless

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

联合类型的集合 scala

在 Scala 中是否有可能有一个联合类型的集合。有几个方法联合类型讨论这里最精彩的答案感觉最原生的,我有这样的事情:

sealed trait StringOrNumber[T]
object StringOrNumber {
    implicit object IntWitness extends StringOrNumber[Int]
    implicit object StringWitness extends StringOrNumber[String]
}
Run Code Online (Sandbox Code Playgroud)

但是当我尝试制作包含两者的地图时

val m: Map[String, Any] = Map("str" -> "hellp", "int" -> 32)
Run Code Online (Sandbox Code Playgroud)

scala 编译器将其视为 [String,Any] 的映射 有没有办法告诉 Scala 编译器这是一个映射 [String, StringOrNumber]

编辑:

我不认为使用上述方法可以创建字符串或联合的集合。我认为它需要是联合类型的另一种方法,因为上述类似于重载方法而不是类型系统中的真正联合类型

functional-programming scala discriminated-union scala-collections

0
推荐指数
1
解决办法
1007
查看次数