scala – 1 ::在foldLeft中列出[Nothing]
如果:
scala> val l = List() // List() same as List[Nothing]() l: List[Nothing] = List() scala> 1 :: l res0: List[Int] = List(1) 要么: scala> 1 :: List[Nothing]() res6: List[Int] = List(1) 为什么然后这不起作用: scala> List(1,2,3). foldLeft( List() ) ((acc,x) => x :: acc) 所以我必须明确键入这个List [Int](): scala> List(1,3). foldLeft( List[Int]() ) ((acc,x) => x :: acc) res3: List[Int] = List(3,1) ? 虽然它在Haskell中,例如: foldl (acc x -> x:acc) [] [1,3] 解决方法
我们来看看scala的foldLeft签名:
List[+A].foldLeft[B](z: B)(f: (B,A) ? B): B 和哈斯克尔的签名: foldl :: (b -> a -> b) -> b -> [a] -> b 他们几乎一样,但是: 1)scala在[伪] curried参数列表之间的类型推断存在问题,只需比较: scala> def aaa[A](a: A)(b: A) = {} aaa: [A](a: A)(b: A)Unit scala> aaa(null: Any)(5) scala> aaa(5)(null: Any) <console>:21: error: type mismatch; found : Any required: Int aaa(5)(null: Any) ^ 因此scala只能从左到右选择更大的类型. 更重要的是,这只是[伪] curried函数的一个问题: scala> def aaa[T](a: T,b: T) = a aaa: [T](a: T,b: T)T scala> aaa(List("a"),List(6.0)) res26: List[Any] = List(a) scala> aaa(List(6.0),List("a")) res27: List[Any] = List(6.0) 在这里,scala不仅选择了更大的类型 – 它已经找到了两种T的常见超类型.所以,它试图在默认情况下选择更大的类型(如果它在左侧部分),但在一个参数列表中寻找一个共同的超类型. 注意:我在谈论[伪] currying,因为具有多个参数列表的方法(B)((B,A)=> B)B仅在eta-expansion之后变为curry函数:foldLeft _给出B => (B,A)=>乙 2)haskell使用List本身的“对象”作为函数的参数,它允许你做甚至: Prelude> let f = foldl (acc x -> x:acc) [] :: [a] -> [a] //here is the polymorphic function Prelude> f [1,3] [3,1] Prelude> f ["1","2","3"] ["3","1"] 在scala中你需要: scala> def f[T](x: List[T]) = x.foldLeft(List[T]()) ((acc,x) => x :: acc) f: [T](x: List[T])List[T] scala> f(List(1,3)) res3: List[Int] = List(3,1) scala> f(List("1","3")) res3: List[String] = List(3,1) 3)最后,让我们重写foldLeft并将monoid的’add’和’identity’放到同一参数列表中(以避免与p.1分开推断): def foldLeft[T,U](l: List[T])(identity: U,add: (U,T) => U) = l.foldLeft(identity)(add) 并定义多态添加操作: scala> def add[A](x: List[A],y: A) = y :: x add: [A](x: List[A],y: A)List[A] 所以你可以: scala> foldLeft(List(1,3))(Nil,add) res63: List[Int] = List(3,1) 与以下比较: scala> List(1,3).foldLeft(Nil)(add) <console>:9: error: polymorphic expression cannot be instantiated to expected type; found : [A,B](x: List[A],y: A)List[A] required: (scala.collection.immutable.Nil.type,Int) => scala.collection.immutable.Nil.type List(1,3).foldLeft(Nil)(add) ^ 不幸的是,scala无法推断lambda的泛型类型,所以你不能: scala> foldLeft(List(1,(acc,x) => x :: acc) <console>:10: error: missing parameter type foldLeft(List(1,x) => x :: acc) 你不能: scala> val a = (acc,x) => x :: acc <console>:7: error: missing parameter type val a = (acc,x) => x :: acc ^ 2& 3)因为scala根本没有多态lambda.无法推断A =>列表[A] => A(其中A是类型参数)来自(acc,x)=> x :: acc(甚至A => A来自val a =(a)=> a),但Haskell可以: Prelude> let lambda = acc x -> x:acc :: [a] -> a -> [a] Prelude> let f = foldl(lambda) [] Prelude> f [1,3] [3,1] 以下是scala中以前定义的添加泛型方法的eta扩展: scala> add _ res2: (List[Nothing],Nothing) => List[Nothing] = <function2> (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- 如何正确捕获unix命令的返回值?
- scala – SORM:如何声明外键?
- angularJS学习小结——$apply方法和$watch方法
- 使用Shell更改进程名称以使用check_procs进行nagios监视
- twitter-bootstrap-3 – 内部模态中的Bootstrap选择无法正确
- angularjs – 如何根据在$routeProvider注册的路由中的参数
- ofbiz的webservice接口提供(4)-支持复杂数据类型方法
- 第一次接触神奇的Bootstrap表单
- Scala开发人员应该了解Java和/或JVM?
- 【专家门诊第115期】时下最热门:Webservice技术在企业中的