2016-09-29 21 views
0

我刚开始用Scala学习FP,所以对这个问题表示歉意。我发现这个练习(练习3.1 https://www.scala-exercises.org/fp_in_scala/functional_data_structures)进行模式匹配,但我有点混淆视听,有闹明白是怎么来的X结果是3FP模式匹配

val x = List(1, 2, 3, 4, 5) match { 
    case Cons(x, Cons(2, Cons(4, _))) => x 
    case Nil => 42 
    case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y 
    case Cons(h, t) => h + sum(t) 
    case _ => 101 
} 

可以请一些与调试通过此方案的步骤帮助这里步 ?我相信这会帮助我理解这个概念。

谢谢。

+0

谢谢大家。现在很清楚:-) – angus

回答

3

Scala中的不可变的ListCons -list。这意味着它由一系列Cons对象组成,并以Nil结尾。例如,您的列表:

List(1, 2, 3, 4, 5) 

会是这样Cons -list:

Cons(1, Cons(2, Cons(3, Cons(4, Cons(5, Nil))))) 

当Scala中列出了模式匹配,你可以使用这个Cons - 结构。这就是那个例子所做的。

让我去通过每个图案的告诉你他们在做什么:

  1. 如果你的第二个元素是2和第三个元素是4。如果是这样的话这一个相匹配,该表达式返回列表的第一个元素。 _意味着你忽略列表的其余部分(所以它可能是3个或更多元素)。

    case Cons(x, Cons(2, Cons(4, _))) => x 
    
  2. 这一个匹配空的列表。如果匹配,则表达式返回42.

    case Nil => 42 
    
  3. 这一个,如果你的第三元件是3和你的第四个要素是4.如果它匹配,则表达式返回列表的两个第一元素的总和相匹配。

    case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y 
    
  4. 这一个匹配所有列表至少有一个元素。如果匹配,则表达式返回第一个元素加上列表其余元素的总和(基本上等于整个列表的总和)。

    case Cons(h, t) => h + sum(t) 
    
  5. 这一个匹配一切。这是默认情况,并返回101.这绝不应该发生,因为所有其他情况都在上面覆盖。

    case _ => 101 
    

正如你希望现在可以看到的,x值变为3,因为它与第三种情况相匹配。这返回1 + 2,等于3.

+1

非常感谢你的很好的解释 – angus

1

List(1, 2, 3, 4, 5)匹配模式Cons(x, Cons(y, Cons(3, Cons(4, _))))

这里x对应于1y对应于图2,3和4是在适当位置,而忽略最后ELEM。

所以x + y = 1 + 2

说明

列表不匹配第一图案(Cons(x, Cons(2, Cons(4, _))))因为后2图案具有4

列表不匹配是Nil秒图案因为列表不是无

列表匹配第三种模式

作为一个模式匹配...其他情况不匹配。因此模式匹配在第三种情况(即成功匹配)后停止匹配

0

列表(1,2,3,4,5)等于Cons(1,Cons(2,Cons(3,Cons(4,Cons 5,无))))。

val x = List(1, 2, 3, 4, 5) match { 
     case Cons(x, Cons(2, Cons(4, _))) => x //1 
     case Nil => 42 //2 
     case Cons(x, Cons(y, Cons(3, Cons(4, _)))) => x + y //3 
     case Cons(h, t) => h + sum(t) //4 
     case _ => 101 //5 
} 

“_”字表示“不关心”

,了解这一点很重要的是供应模式将影响结果的第一场比赛。

  1. 不能,因为它的缺点(2,缺点(,缺点(4,....)))
  2. 不能,因为它不是零,这是缺点
  3. 这是因为供给X可以等于1,ÿ等于2的图案其余的继续。当他看到“_”字,他不在乎什么,他看到这意味着它提供
0

正如您可以通过名称pattern-matching猜测的那样,case中提供的整个表达式被视为Pattern,并与匹配的值匹配。

在这种情况下,您的匹配值是List(1, 2, 3, 4, 5)。并且列表还可以使用infix cons-::(或postfix cons-Cons)来表示。

所以这个列表可以表示为(使用infix cons),

1 :: 2 :: 3 :: 4 :: 5 :: Nil 

或者也可以(使用postfix cons),

Cons(1, Cons(2, Cons(3, Cons(4, Cons(5, Nil))))` 

,因此你可以看到,它的模式Cons(x, Cons(y, Cons(3, Cons(4, _))))相匹配,因此x被匹配到值1y至值2,其使得结果x + y3

0

该列表与第三种情况相匹配,所以这就是您正在查看的内容。两个“列表”中的模式是相同的。因此,第三种情况将产生x + y的结果,在这种情况下为3.要看到这一点,请回头看看原始参数List(1, 2, 3, 4, 5)并观察它与第三种情况的匹配程度; x = 1y = 2;所以x + y = 3