当一个类在Scala中定义.map函数时,有没有办法通过继承(或其他方
我的问题在下面的代码中表达.
我正在尝试获取一些具有.map功能的输入.我知道如果我调用.map,它会返回一个Int给我. // In my case,they are different representations of Ints // By that I mean that in the end it all boils down to Int val list: Seq[Int] = Seq(1,2,3,4) val optInt: Option[Int] = Some(1) // I can use a .map with a Seq,check! list.map { value => println(value) } // I can use it with an Option,check! optInt.map { value => println(value) } // Well,you're asking yourself why do I have to do it,// Why don't I use foreach to solve my problem. Check! list.foreach(println) optInt.foreach(println) // The problem is that I don't know what I'm going to get as input // The only thing I know is that it's "mappable" (it has the .map function) // And that if I were to apply .map it would return Ints to me // Like this: def printValues(genericInputThatHasMap: ???) { genericInputThatHasMap.map { value => println(value) } } // The point is,what do I have to do to have this functionality? // I'm researching right now,but I still haven't found anything. // That's why I'm asking it here =( // this works: def printValues(genericInputThatHasMap: Seq[Int]) { genericInputThatHasMap.map { value => println(value) } } 提前致谢!干杯! 解决方法
首先要快速了解地图和foreach.如果您只对集合中每个项目执行带副作用的操作(例如,打印到标准输出或文件等)感兴趣,请使用foreach.如果您对通过转换旧元素中的每个元素来创建新集合感兴趣,请使用map.当您编写xs.map(println)时,您实际上会打印该集合的所有元素,但您也会获得一个(完全无用的)单元集合,并且还可能会混淆未来的代码读者 – 包括你自己 – 期望foreach在这样的情况下使用.
现在问你的问题.你已经遇到了我认为Scala标准库最丑陋的事情之一 – 事实上名为map和foreach(和flatMap)的方法在语言层面得到了与特定类型无关的神奇处理定义它们.例如,我可以这样写: case class Foo(n: Int) { def foreach(f: Int => Unit) { (0 until n) foreach f } } 并在这样的for循环中使用它,只是因为我已将我的方法命名为foreach: for (i <- Foo(10)) println(i) 您可以使用structural types在您自己的代码中执行类似操作: def printValues(xs: { def foreach(f: (Int) => Unit): Unit }) { xs foreach println } 这里任何具有适当类型的foreach方法的xs – 例如Option [Int]或List [Int] – 将按预期编译和工作. 当您尝试使用map或flatMap时,结构类型变得更加混乱,并且在其他方??面不令人满意 – 例如,由于使用运行时反射,它们会产生一些丑陋的开销.他们实际上必须是explicitly enabled in Scala 2.10,以避免因这些原因发出警告. 正如Senia的回答所指出的那样,Scalaz library通过使用像Monad这样的type classes提供了更加一致的方法来解决问题.但是,在这样的情况下,你不会想要使用Monad:它比你需要的更强大的抽象.你可以使用Each来提供foreach,使用Functor来提供地图.例如,在Scalaz 7中: import scalaz._,Scalaz._ def printValues[F[_]: Each](xs: F[Int]) = xs foreach println 要么: def incremented[F[_]: Functor](xs: F[Int]) = xs map (_ + 1) 总而言之,您可以使用结构类型以标准的,惯用的,但可以说是丑陋的方式执行您想要的操作,或者您可以使用Scalaz来获得更清晰的解决方案,但代价是新的依赖项. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |