与自定义组合/运算符匹配 [英] Matching with custom combinations/operators

查看:55
本文介绍了与自定义组合/运算符匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道你可以用类似的方式对列表进行匹配

val list = List(1,2,3)列表匹配{case head::tail =>头案例_ =>//任何}

所以我开始想知道这是如何工作的.如果我理解正确, :: 只是一个操作符,那么是什么阻止我做类似的事情

4 匹配 {情况 x + 2 =>x//我希望这里 x=2}

如果有办法创建这种功能,是怎么做的;如果没有,那为什么?

解决方案

模式匹配接受输入并使用 unapply 函数将其分解.因此,在您的情况下, unapply(4) 必须返回总和为 4 的两个数字.但是,有许多对总和为 4,因此该函数不知道该怎么做.

您需要的是 2 以某种方式被 unapply 函数访问.一个存储 2 的特例类将适用于此:

case class Sum(addto: Int) {def unapply(i: Int) = Some(i - addto)}val Sum2 = Sum(2)val Sum2(x) = 5//x = 3

(为了紧凑性,能够执行类似 val Sum(2)(y) = 5 之类的操作会很好,但 Scala 不允许参数化提取器;请参阅 这里.)>

head::tail 之所以起作用,是因为只有一种方法可以将列表的头部与尾部分开.

::+ 之间没有什么本质上的特殊:如果您对它的使用方式有一个预先确定的想法,您可以使用 +打破一个数字.例如,如果您希望 + 表示分成两半",那么您可以执行以下操作:

对象 + {def unapply(i: Int) = Some(i-i/2, i/2)}

并像这样使用它:

scala>值 a + b = 4一个:整数 = 2b: 整数 = 2标度>价值 c + d = 5c: 整数 = 3d: 整数 = 2

最后,this 解释说,当模式匹配,A op Bop(A,B) 意思相同,这使得语法看起来不错.

I know that you can do matching on lists in a way like

val list = List(1,2,3)
list match {
  case head::tail => head
  case _ => //whatever
}

so I started to wonder how this works. If I understand correctly, :: is just an operator, so what's to stop me from doing something like

4 match {
  case x + 2 => x //I would expect x=2 here
}

If there is a way to create this kind of functionality, how is it done; if not, then why?

解决方案

Pattern matching takes the input and decomposes it with an unapply function. So in your case, unapply(4) would have to return the two numbers that sum to 4. However, there are many pairs that sum to 4, so the function wouldn't know what to do.

What you need is for the 2 to be accessible to the unapply function somehow. A special case class that stores the 2 would work for this:

case class Sum(addto: Int) {
    def unapply(i: Int) = Some(i - addto)
}

val Sum2 = Sum(2)
val Sum2(x) = 5  // x = 3

(It would be nice to be able to do something like val Sum(2)(y) = 5 for compactness, but Scala doesn't allow parameterized extractors; see here.)

[EDIT: This is a little silly, but you could actually do the following too:

val `2 +` = Sum(2)
val `2 +`(y) = 5  // y = 3

]

EDIT: The reason the head::tail thing works is that there is exactly one way to split the head from the tail of a list.

There's nothing inherently special about :: versus +: you could use + if you had a predetermined idea of how you wanted it to break a number. For example, if you wanted + to mean "split in half", then you could do something like:

object + {
    def unapply(i: Int) = Some(i-i/2, i/2)
}

and use it like:

scala> val a + b = 4
a: Int = 2
b: Int = 2

scala> val c + d = 5
c: Int = 3
d: Int = 2

EDIT: Finally, this explains that, when pattern matching, A op B means the same thing as op(A,B), which makes the syntax look nice.

这篇关于与自定义组合/运算符匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆