用于理解的函数式组合使用Char而不是String
我试图使用理解来构造我的对象调用,下面是我的简单实现:用于理解的函数式组合使用Char而不是String,string,scala,functional-programming,function-composition,for-comprehension,String,Scala,Functional Programming,Function Composition,For Comprehension,我试图使用理解来构造我的对象调用,下面是我的简单实现: object FuncA extends (String => Int => String) { override def apply(str: String): Int => String = i => { s"${(str.toInt + i).toString}" } } object FuncB extends (String => Int) { overr
object FuncA extends (String => Int => String) {
override def apply(str: String): Int => String = i => {
s"${(str.toInt + i).toString}"
}
}
object FuncB extends (String => Int) {
override def apply(str: String): Int = {
str.toInt
}
}
for {
funcAStr <- FuncA("1")(1)
funcBStr <- FuncB(funcAStr) // Fails here
} yield {
println(s"Final String incremented as int is $funcBStr")
}
对象FuncA扩展(String=>Int=>String){
覆盖def apply(str:String):Int=>String=i=>{
s“${(str.toInt+i.toString}”
}
}
对象FuncB扩展(字符串=>Int){
覆盖定义应用(str:String):Int={
托因街
}
}
为了{
funcAStr使用
尝试函数合成,然后像这样
(FuncA("1") andThen FuncB)(1)
哪个输出
res0: Int = 2
尽管包含了for loop
标记,Scala中的for
并没有定义循环。for
是定义map
、flatMap
和with filter
调用序列的简捷方法
您的代码转换为:
FuncA("1")(1).flatMap{ funcAStr =>
FuncB(funcAStr).map{ funcBStr =>
println(s"Final String incremented as int is $funcBStr")
}
}
Func(“1”)(1)
返回String
。String
上的flatMap
方法依次获取字符串的每个字符,因此funcAStr
在Scala中实际上是Char
而不是String
,map
或foreac>的嵌套调用的语法糖分h
。简化后,基本规则是每个箭头将转换为嵌套的flatMap
,最后一个箭头将转换为map
或foreach
,具体取决于您是否使用yield
在您的情况下,理解将转化为类似于:
val r: Seq[Unit] =
FuncA("1")(1).flatMap{ funcAStr : Char =>
FuncB(funcAStr).map{ funcBStr: Int =>
println(s"Final String incremented as int is $funcBStr")
}
}
而且它实际上没有多大意义,因为首先funcBStr
需要String
而不是Char
。但是即使您修复了它,编译器也会抱怨,因为flatMap
需要可以表示为gentraversableone[B]
的东西
所以我想你不应该在你的用例中使用理解
如果您使用IntelliJ,您可以使用快捷键Ctrl+Alt+D,这将显示Desugar Scala代码对话框。然后您将能够选择expand for comprehension,并向您展示如何将for comprehension转换为flatMap
/map
调用。我可以做到这一点,但我想坚持使用for comprehension,因为我有很多方法se我想创作的功能对象!