在scala

时间:2017-03-11 22:31:37

标签: scala functional-programming

我是scala的新手。目前我正在尝试开发一个计算器作为scala项目。 但在试图找到总和时,我遇到了问题。以下代码无法编译。

def add [T](values :List[T]) : Option[T]={ 
  if (values.isInstanceOf[String]) {
    None
  }
  else if(values.isInstanceOf[Int] || values.isInstanceOf[Long] || values.isInstanceOf[Double]) {
    Some(values.sum)
  } 
}

2 个答案:

答案 0 :(得分:1)

当你对某种语言不熟悉时,重要的是要慢慢开始并发现抽象,而不是立即强加它们,而没有经验使其发挥作用。我还认为仅仅依靠标准库函数(除非你很匆忙)(如sum)或查看第三方库是不明智的,直到您完全理解标准库提供的内容为止。

换句话说,首先让我们看看为Int解决问题的方法:

def add(values: List[Int]) = values.reduce((a, b) => a + b)

reduce函数有效,因为结果的类型与列表中的类型相匹配。内容为Int s,总和为Int。你也会发现这可以通过一些语法糖来简化:

def add(values: List[Int]) = values.reduce(_ + _)

等到你看到在Scala中使用下划线的所有方法。

在您继续学习的过程中,您会发现为了累积与不同类型的值而不是列表中的内容,您可以使用其中一个{{1} } 方法。但他们也可以在这里工作,所以例如你也可以这样做:

fold*

现在尝试为def add(values: List[Int]) = values.foldLeft(0)(_ + _) Long甚至Double定义相同的功能。您会发现实现几乎完全相同。

只有当您看到真正类似的实现时,如果不相同,您甚至应该考虑抽象。解决此问题的一个方法是type classes。然而,对于初学者来说,它们并不容易。 Daniel Westheide在这个主题上写了一篇很棒的post,坦率地说,当你学习Scala时,你会很好地阅读整个series

我真的简化了一些事情,并且掩盖了很多主题(比如为什么String有两个参数列表,其中第一个是0,或者那些疯狂的foldLeft事情在Daniel&#中39; s类型的帖子),但我的建议是要耐心,慢慢行动。 Scala并不容易,但你会得到它。

(但如果你很匆忙并且你是初学者,我认为你最好只使用implicit然后为每种类型编写单独的函数。这将是敏捷作者Kenny Rubin的一个例子。会打电话给那些必要的"或者#34;不可避免的技术债务,这些都是初学者所期待的。只需稍后重构。)

答案 1 :(得分:0)

或更通用(例如amm):

@ import $ivy.`org.typelevel:cats_2.12:0.8.1` 
import $ivy.$                              
@ import cats._, cats.implicits._ 
import cats._, cats.implicits._
@ List(1, 2, 3).combineAll 
res2: Int = 6
@ List("1", "2", "3").combineAll 
res3: String = "123"
@ List(List(1, 2), List(), List(3)).combineAll 
res5: List[Int] = List(1, 2, 3)

或通过fiddle。它的工作原理是使用MonoidTraversable类型类。