在代码出现的第 12 天,我使用 monocle(scala 中的一个镜头库)重构了我的代码。
是否可以改进此代码:
type Register = String
type Mem = Map[String, Int]
@Lenses
case class State(mem: Mem, pointer: Int)
def processInstruction(instructions: Seq[Instruction]): State => State = { s =>
(instructions(s.pointer) match {
case Inc(r) =>
State.pointer.modify( _ + 1) andThen (State.mem composeLens at(r)).modify(_.map(_ + 1))
case Dec(r) =>
State.pointer.modify( _ + 1) andThen (State.mem composeLens at(r)).modify(_.map(_ - 1))
case CpyInt(v, to) =>
State.pointer.modify( _ + 1) andThen (State.mem composeLens at(to)).set(Some(v))
case CpyReg(from, to) =>
State.pointer.modify( _ + 1) andThen (State.mem composeLens at(to)).set(Some(s.mem(from)))
case Jnz(r, v) => if (r != "1" && s.mem(r) == 0)
State.pointer.modify( _ + 1)
else
State.pointer.modify( _ + v )
}).apply(s)
}
而这里又是一个尝试,分离每个字段的修改
def processInstruction2(instructions: Seq[Instruction]): State => State = { s =>
val ptr = instructions(s.pointer) match {
case Jnz(r, v) if !(r != "1" && s.mem(r) == 0) => State.pointer.modify(_ + v)
case _ => State.pointer.modify(_ + 1)
}
val mem = instructions(s.pointer) match {
case Inc(r) => (State.mem composeLens at(r)).modify(_.map(_ + 1))
case Dec(r) => (State.mem composeLens at(r)).modify(_.map(_ - 1))
case CpyInt(v, to) => (State.mem composeLens at(to)).set(Some(v))
case CpyReg(from, to) => (State.mem composeLens at(to)).set(Some(s.mem(from)))
case _ => identity[State]
}
(ptr andThen mem)(s)
}
还有一个问题:有没有办法Map.withDefaultValue
与单片眼镜一起使用?
完整代码在这里:https ://gist.github.com/YannMoisan/b8ba25afc041d88706545527d9ec1988