Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 如何多次调用“flatMap”自以为是的方式 问题:_Scala_Functional Programming_Flatmap - Fatal编程技术网

Scala 如何多次调用“flatMap”自以为是的方式 问题:

Scala 如何多次调用“flatMap”自以为是的方式 问题:,scala,functional-programming,flatmap,Scala,Functional Programming,Flatmap,当玩玩具示例-位置时,骑士可以从某个位置开始移动n步,然后到达棋盘上x-我想知道是否存在更干净的解决方案(在简洁性和功能编程的意义上) 执行flatMap(暂时忽略过滤器)一定次数(每次移动一次) 有一种(甚至)更像FP的编码方式 我试过的 一个简单的递归变量移动(…) 使用函数组合的变体move2(…) 代码 问题: 为什么要像阿尔瓦罗建议的那样使用Scalaz和Kleisli?(不是指责备,我想要争论;) 是否可能有更优雅的解决方案 不知道是否还有FP,但这里有一个版本使用scal

当玩玩具示例-位置时,骑士可以从某个位置开始移动
n
步,然后到达棋盘上
x
-我想知道是否存在更干净的解决方案(在简洁性和功能编程的意义上)

  • 执行
    flatMap
    (暂时忽略
    过滤器
    )一定次数(每次移动一次)
  • 有一种(甚至)更像FP的编码方式
我试过的
  • 一个简单的递归变量移动(…)
  • 使用函数组合的变体
    move2(…)
代码 问题:
  • 为什么要像阿尔瓦罗建议的那样使用Scalaz和
    Kleisli
    ?(不是指责备,我想要争论;)
  • 是否可能有更优雅的解决方案

不知道是否还有FP,但这里有一个版本使用scalaz
=>

import scalaz.Kleisli
import scalaz.syntax.kleisli._
import scalaz.std.list._

def move3 (startPos: Position, steps: Int, chessboard: Chessboard) : Set[Position] = {
  val validMove = Kleisli {a: Position => knightMoves(a).filter(chessboard.positionOnBoard).toList}
  List.fill(steps)(validMove).reduce(_ >=> _)(startPos).toSet
}
必须使用List,因为Set没有绑定实例


更新:删除了
step-1
,这是我试用的上一个版本的遗留版本。

看起来更适合我老实说,这并不是代码审查。首先,方法的结构得到了很好的定义。第二,给出了一个完整的运行示例。中心问题(如标题中强调的)是如何以最简洁和功能性的编程方式多次执行
flatMap
。谢谢你的理解!我想代码审查的目的不是让它工作,而是简化和美化代码
列表。填充(步骤1)
似乎不正确。至少对于Scala来说,它必须是
List.fill(step)
。其次,你能解释一下为什么需要
KleislI
?(见我的编辑方法2b))@MartinSenne Kleisli在我看来(不是专家),当我们知道第一个单子产生的值直接进入下一个单子时,似乎更合适、更简洁。对于
flatMap
,情况并非总是如此,它可能被忽略或被其他东西取代。
def move2b(startPos: Position, steps: Int, chessboard: Chessboard) : Set[Position] = {
  val nextFnc : Set[Position] => Set[Position] = {
    _.flatMap( knightMoves(_).filter( chessboard.positionOnBoard(_)) )
  }

  List.fill(steps)(nextFnc).reduce(_ compose _)(Set(startPos))
}
import scalaz.Kleisli
import scalaz.syntax.kleisli._
import scalaz.std.list._

def move3 (startPos: Position, steps: Int, chessboard: Chessboard) : Set[Position] = {
  val validMove = Kleisli {a: Position => knightMoves(a).filter(chessboard.positionOnBoard).toList}
  List.fill(steps)(validMove).reduce(_ >=> _)(startPos).toSet
}