标签: unapply

unapply和unapplySeq有什么区别?

为什么Scala有unapplyunapplySeq?两者有什么区别?我什么时候应该更喜欢一个?

scala pattern-matching unapply

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

如何模式匹配具有多个参数列表的类?

考虑这个课程:

class DateTime(year: Int, month: Int, day: Int)(hour: Int, minute: Int, second: Int)
Run Code Online (Sandbox Code Playgroud)

unapply方法将如何,如果我想匹配以下内容:

dt match {
  case DateTime(2012, 12, 12)(12, _, _) => // December 12th 2012, 12 o'clock
  /* ... */
}
Run Code Online (Sandbox Code Playgroud)

我试过这个:

def unapply(dt: DateTime) = 
  Some((dt.year, dt.month, dt.day),(dt.hour, dt.minute, dt.second))
Run Code Online (Sandbox Code Playgroud)

但这并没有真正起作用.

scala class case pattern-matching unapply

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

Scala:Case类unapply vs手动实现和类型擦除

我试图了解Scala对Case Classes的作用,使它们对类型擦除警告有所不同.

假设我们有以下简单的类结构.它基本上是Either:

abstract class BlackOrWhite[A, B]

case class Black[A,B]( val left: A ) extends BlackOrWhite[A,B]

case class White[A,B]( val right: B ) extends BlackOrWhite[A,B]
Run Code Online (Sandbox Code Playgroud)

而你正试图像这样使用它:

object Main extends App {

    def echo[A,B] ( input: BlackOrWhite[A,B] ) = input match {
        case Black(left) => println( "Black: " + left )
        case White(right) => println( "White: " + right )
    }

    echo( Black[String, Int]( "String!" ) )
    echo( White[String, Int]( 1234 ) )
}
Run Code Online (Sandbox Code Playgroud)

一切都编译和运行没有任何问题.但是,当我unapply自己尝试实现该方法时,编译器会发出警告.我使用了以下类结构与Main上面相同的类: …

scala pattern-matching type-erasure case-class unapply

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

Scala中更高级别类型的推断有哪些限制?

在以下简化的示例代码中:

case class One[A](a: A) // An identity functor
case class Twice[F[_], A](a: F[A], b: F[A]) // A functor transformer
type Twice1[F[_]] = ({type L[?] = Twice[F, ?]}) // We'll use Twice1[F]#L when we'd like to write Twice[F]

trait Applicative[F[_]] // Members omitted
val applicativeOne: Applicative[One] = null // Implementation omitted
def applicativeTwice[F[_]](implicit inner: Applicative[F]): Applicative[({type L[?] = Twice[F, ?]})#L] = null
Run Code Online (Sandbox Code Playgroud)

我可以在applicativeOne上调用applicativeTwice,并且类型推断工作,一旦我尝试在applicativeTwice(applicativeOne)上调用它,推理就会失败:

val aOK = applicativeTwice(applicativeOne)
val bOK = applicativeTwice[Twice1[One]#L](applicativeTwice(applicativeOne))
val cFAILS = applicativeTwice(applicativeTwice(applicativeOne))
Run Code Online (Sandbox Code Playgroud)

scala 2.10.0中的错误是

- type mismatch; …
Run Code Online (Sandbox Code Playgroud)

scala type-inference unapply higher-kinded-types

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

Scala"提取器"可以在unapply上使用泛型吗?

我不能在unapply提取器的方法上使用泛型以及隐式"转换器"来支持特定于参数化类型的模式匹配吗?

我想这样做(注意使用[T]unapply),

trait StringDecoder[A] {
  def fromString(string: String): Option[A]
}

object ExampleExtractor {
  def unapply[T](a: String)(implicit evidence: StringDecoder[T]): Option[T] = {
    evidence.fromString(a)
  }
}    

object Example extends App {          

 implicit val stringDecoder = new StringDecoder[String] {
    def fromString(string: String): Option[String] = Some(string)
  }

  implicit val intDecoder = new StringDecoder[Int] {
    def fromString(string: String): Option[Int] = Some(string.charAt(0).toInt)
  }

  val result = "hello" match {
    case ExampleExtractor[String](x) => x     // <- type hint barfs …
Run Code Online (Sandbox Code Playgroud)

generics scala unapply extractor

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

是否可以在case语句的主体中(或者在使用提取器的任何其他地方)使用参数自定义提取器?

基本上,我希望能够构建一个自定义提取器,而无需在使用它之前将其存储在变量中.

这不是我将如何使用它的一个真实示例,它更可能用于正则表达式或其他字符串模式(如构造),但希望它能解释我正在寻找的内容:

def someExtractorBuilder(arg:Boolean) = new {
  def unapply(s:String):Option[String] = if(arg) Some(s) else None
}

//I would like to be able to use something like this 
val {someExtractorBuilder(true)}(result) = "test"
"test" match {case {someExtractorBuilder(true)}(result) => result }

//instead I would have to do this:
val customExtractor = someExtractorBuilder(true)
val customExtractor(result) = "test"
"test" match {case customExtractor(result) => result}
Run Code Online (Sandbox Code Playgroud)

当只做一个自定义提取器时,它没有太大的区别,但如果你为case语句构建一个大的提取器列表,它可能会通过将所有提取器与它们的使用分开来使事情变得更难.

我希望答案是不,你不能这样做,但我想我先问一下:D

scala unapply extractor

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

Scala - 可以取消应用返回varargs?

L1下面的对象有效.我可以L1通过传入varargs 来"创建" ,这很好,但我希望能够L1使用相同的语法分配给一个.不幸的是,我在这里完成它的方式需要更粗略的嵌套Array内部语法L1.

object L1 {
    def apply(stuff: String*) = stuff.mkString(",")
    def unapply(s: String) = Some(s.split(","))
}
val x1 = L1("1", "2", "3")
val L1(Array(a, b, c)) = x1
println("a=%s, b=%s, c=%s".format(a,b,c))
Run Code Online (Sandbox Code Playgroud)

我尝试以一种显而易见的方式实现这一目标,L2如下所示:

object L2 {
    def apply(stuff: String*) = stuff.mkString(",")
    def unapply(s: String) = Some(s.split(","):_*)
}
val x2 = L2("4", "5", "6")
val L2(d,e,f) = x2
println("d=%s, e=%s, f=%s".format(d,e,f))
Run Code Online (Sandbox Code Playgroud)

但是这给出了错误:

error: no `: _*' annotation allowed here 
(such …
Run Code Online (Sandbox Code Playgroud)

scala variadic-functions unapply

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

Scala - 使用unapply进行隐式转换

我想要一个提取器来隐式转换它的参数,但它似乎不起作用.考虑这个非常简单的情况:

case class MyString(s: String) {}

implicit def string2mystring(x: String): MyString = new MyString(x)
implicit def mystring2string(x: MyString) = x.s

object Apply {
    def unapply(s: MyString): Option[String] = Some(s)
}
Run Code Online (Sandbox Code Playgroud)

但是我无法像我期望的那样使用它:

val Apply(z) = "a"  // error: scrutinee is incompatible with pattern type
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么它无法将参数转换StringMyString?我希望它可以string2mystring("a")即时通话.很明显,我可以解决这个问题val Apply(y) = MyString("a"),但似乎我不应该这样做.

注意:这个问题类似于这一个,而是1)一个不确实对为什么发生这种情况,2)的例子是比它需要更加复杂的一个很好的答案.

scala implicit-conversion unapply

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

Scala - 向Int添加unapply

我希望能够这样做:

scala> val Int(i) = "1"
i: Int = 1
Run Code Online (Sandbox Code Playgroud)

但是Int没有unapply方法.

我找到了这个答案,它给出了如何隐式地将方法添加到现有对象的说明,所以我试了一下.他们提供的解决方案有效,但遗憾的是不适用于模式匹配.这就是我所拥有的:

object UnapplyInt {
  val IntRE = """^(\d+)$""".r
  def unapply(v: String): Option[Int] = v match {
    case IntRE(s) => Some(s.toInt)
    case _ => None
  }
}
implicit def int2unapplyInt(objA: Int.type) = UnapplyInt
Run Code Online (Sandbox Code Playgroud)

这些测试用例都很好:

val UnapplyInt(i) = "1"       // pattern matching with unapply is fine
val i = Int.unapply("1").get  // implicit conversion is fine
Run Code Online (Sandbox Code Playgroud)

但我想要的那个失败了:

scala> val Int(i) = "1"
<console>:10: error: object Int …
Run Code Online (Sandbox Code Playgroud)

scala implicit-conversion unapply

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

如何在多态unapply中使用提取器?

我真的没有得到这个小东西.我有一个抽象类Box,有几个不同类型的子类.例如

abstract class Box
class StringBox(val sValue : String) extends Box
Run Code Online (Sandbox Code Playgroud)

Box的伴侣对象中的apply方法很简单:

object Box{
    def apply(s: String)  = new StringBox(s)
    def apply(b: Boolean) = new BooleanBox(b)
    def apply(d: Double)  = new DoubleBox(d)
}
Run Code Online (Sandbox Code Playgroud)

所以我可以写

    val sb = Box("StringBox)
Run Code Online (Sandbox Code Playgroud)

好的,写不应用会带来一些麻烦.我的第一个想法是在类型上使用模式匹配,如下所示:

def unapply(b: Box) = b match {
  case sb: StringBox => Some(sb.sValue)
  case bb: BooleanBox => Some(bb.bValue)
  case db: DoubleBox => Some(db.dValue)
  case _ => None
Run Code Online (Sandbox Code Playgroud)

}

由于类型擦除,这根本不起作用.

第二次尝试是具有类型T的通用Box [T],并且在每个子类中重新定义了抽象类型成员.例如:

 abstract class Box[T] {def value : T}
 class StringBox(val sValue : …
Run Code Online (Sandbox Code Playgroud)

scala unapply extractor

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