Scala函数式编程课后习题答案(第六章)
来源:互联网 发布:同轴圆柱形电容器算法 编辑:程序博客网 时间:2024/05/25 18:10
Scala函数式编程课后习题答案(第六章)
练习6.1,6.2,6.3,6.4,6.5
trait RNG { def nextInt:(Int,RNG)}case class seedRNG(seed:Long) extends RNG{ def nextInt:(Int,RNG)={ val seed2 = (seed*0x5DEECE66DL + 0xBL) & 0xFFFFFFFFFFFFL ((seed2 >>> 16).asInstanceOf[Int],seedRNG(seed2)) }}object RNG{ def double(rng:RNG):(Double,RNG) ={ val (i,rng2) = rng.nextInt if (i == Int.MaxValue) (0.0,rng2) else (i.toDouble/Int.MaxValue.toDouble,rng2) } def nonNegativeInt(rng: RNG): (Int, RNG)={ val (i,rng2) = rng.nextInt if (i == Int.MaxValue) (Int.MaxValue,rng2) else (i.abs,rng2) } def nextBoolean(rng:RNG):(Boolean,RNG)={ rng.nextInt match { case (i,rng2) => (i%2==0,rng2) } } def intDouble(rng:RNG):((Int,Double),RNG)={ val (i,rng2)= nonNegativeInt(rng) val (d,rng3)= double(rng2) ((i,d),rng3) } def doubleInt(rng:RNG):((Double,Int),RNG) ={ val (d,rng2) = double(rng) val (i,rng3) = nonNegativeInt(rng2) ((d,i),rng3) } def double3(rng:RNG):((Double,Double,Double),RNG)={ val (d1,rng2)= double(rng) val (d2,rng3)= double(rng2) val (d3,rng4)= double(rng3) ((d1,d2,d3),rng4) } def ints(count:Int)(rng:RNG):(List[Int],RNG)={ def go(count:Int,rng:RNG,acc:List[Int]):(List[Int],RNG)={ if (count<=0) (acc,rng) else{ val (i,rng2) = rng.nextInt go(count-1,rng2,i::acc) } } go(count,rng,Nil:List[Int]) } type Rand[+A] = RNG =>(A,RNG) val int:Rand[Int] =_.nextInt def unit[A](a:A):Rand[A]= rng => (a,rng) def map[A,B](s:Rand[A])(f: A=>B):Rand[B]={ rng =>{ val (a, rng2) = s(rng) (f(a),rng2) } } def nonNegativeEven: Rand[Int] = map(nonNegativeInt)(i =>i-i%2) def double2(rng:RNG):Rand[Double]= {map(nonNegativeInt){ _ /(Int.MaxValue.toDouble+1)}}}
6.11
/** * Created by Abbott on 2017/5/27. */object State { case class State[S,+A](run:S =>(A,S)){ def flatMap[B](f:A => State[S,B]):State[S,B]= State[S,B]{ s =>{ val (a,s1) = run(s) f(a).run(s1) } } def map[B](f:A => B):State[S,B]= flatMap{a=>unit(f(a))} def map2[B,C](sb:State[S,B])(f:(A,B)=>C):State[S,C]= flatMap{a=>sb.map{ b=>f(a,b)}} def map3[B,C,D](sb:State[S,B],sc:State[S,C])(f:(A,B,C)=>D):State[S,D]=flatMap{a=>sb.flatMap{b=>sc.map(c=>f(a,b,c))}} } def unit[S,A](a:A) = State[S,A](s =>(a,s)) def getState[S]:State[S,S] = State[S,S]{s => (s,s)} def setState[S](s:S):State[S,Unit] =State[S,Unit] {_ => ((),s)} type candy = Int type coin = Int sealed trait Input case object Coin extends Input case object Turn extends Input case class Machine(locked:Boolean, candies:Int, coins:Int) //OOP风格 def simulateMachine(inputs:List[Input]):State[Machine,coin]={ def transition(input:Input, machine:Machine):Machine={ (input,machine) match { case (_, Machine(_,0,_)) => machine //没有糖果的贩售机对任何操作都不做反应 case (Turn, Machine(true,_,_)) => machine //在锁定状态下扭动旋钮贩售机不做反应 case (Coin, Machine(false,_,_)) => machine //在放开状态下投入硬币贩售机不做反应 case (Coin, Machine(true,_,nCoin)) => machine.copy(locked = false,coins = nCoin +1) //锁定状态,投入硬币,变成打开状态 case (Turn,Machine(false,nCandy,_)) => machine.copy(locked = true,candies = nCandy-1) //放开状态,扭动旋钮,变成关闭状态 } } def execute(inputs:List[Input],machine: Machine): Machine= { inputs match { case Nil => machine case h::t => execute(t,transition(h,machine)) } } for{ s0 <- getState //起始状态 _ <- setState(execute(inputs,s0)) //执行状态 s1 <- getState //执行后状态 } yield s1.coins } //FP风格 def modify[S](f: S => S): State[S,Unit] ={ for { s0 <- getState _ <- setState(f(s0)) }yield () } //递归方式实现sequence def sequence[S,A](xs:List[State[S,A]]):State[S,List[A]] ={ def go(s:S, actList:List[State[S,A]], acc:List[A]): (List[A],S) ={ actList match { case Nil => (acc.reverse,s) //纠正排序得到结果集 case h::t => h.run(s) match {case (a2,s2) => go(s2,t,a2::acc)} //按照List元素递归处理 } } State(s => go(s,xs,List())) } //右折叠算法实现sequence def sequenceByRight[S,A](xs:List[State[S,A]]):State[S,List[A]] ={ xs.foldRight(unit[S,List[A]](List())){(f,acc) => f.map2(acc)(_::_)} } //左折叠算法实现sequence def sequenceByLift[S,A](xs:List[State[S,A]]):State[S,List[A]] ={ xs.reverse.foldLeft(unit[S,List[A]](List())){(acc,f) => f.map2(acc)(_::_)} } //FP实现售货机 def simulateMachineFP(inputs:List[Input]):State[Machine,coin]={ for{ _ <- sequenceByLift{ inputs.map{ input => modify{ machine:Machine => { (input,machine) match { case (_, Machine(_,0,_)) => machine //没有糖果的贩售机对任何操作都不做反应 case (Turn, Machine(true,_,_)) => machine //在锁定状态下扭动旋钮贩售机不做反应 case (Coin, Machine(false,_,_)) => machine //在放开状态下投入硬币贩售机不做反应 case (Coin, Machine(true, nCardy, nCoin)) => Machine(false, nCardy, nCoin+1) //关闭状态,投币+1,状态为开启 case (Turn, Machine(false, nCardy, nCoin)) => Machine(true, nCardy-1, nCoin) //开启状态,旋钮,糖-1,状态为关闭 } } } } } s <- getState } yield s.coins } //FP风格提炼逻辑的售货机 def simulateMachineConcise(inputs:List[Input]):State[Machine,coin]={ def transition(input: Input, machine: Machine): Machine ={ (input,machine) match { case (_, Machine(_,0,_)) => machine //没有糖果的贩售机对任何操作都不做反应 case (Turn, Machine(true,_,_)) => machine //在锁定状态下扭动旋钮贩售机不做反应 case (Coin, Machine(false,_,_)) => machine //在放开状态下投入硬币贩售机不做反应 case (Coin, Machine(true, nCardy, nCoin)) => Machine(false, nCardy, nCoin+1) //关闭状态,投币+1,状态为开启 case (Turn, Machine(false, nCardy, nCoin)) => Machine(true, nCardy-1, nCoin) //开启状态,旋钮,糖-1,状态为关闭 } } for{ _ <- sequenceByLift(inputs.map{input =>modify{machine:Machine =>transition(input,machine)}}) s <- getState } yield s.coins } def main(args: Array[String]): Unit = { val inputs = List(Coin, Turn, Coin, Turn, Turn, Coin, Coin, Coin, Turn) println(simulateMachine(inputs).run(Machine(true,3,0))) //println(simulateMachineFP(inputs).run(Machine(true,3,0))) //println(simulateMachineConcise(inputs).run(Machine(true,3,0))) }}
阅读全文
0 0
- Scala函数式编程课后习题答案(第六章)
- Scala函数式编程课后习题答案(第五章)
- Scala函数式编程课后习题答案(第三章)(更新ing)
- Scala函数式编程课后习题答案(第四章)(更新ing)
- Python核心编程(第二版)第六章课后习题答案
- 模板元编程第六章课后习题(非答案)20151206
- 快学Scala 第六章习题答案
- 快学Scala 第六章习题答案
- 快学 scala 第二章课后习题答案
- 郑莉版c语言第六章课后习题答案
- C++Primer 中文版 第五版 第六章课后习题答案
- 《C语言的科学与艺术》课后习题答案第六章(部分)
- 《C语言程序设计教程》(主编黄迪明、余勤)第六章课后习题答案
- python核心编程-第六章习题答案
- Oracle第六章 分组函数习题答案
- 06 快学scala第六章习题答案
- 编程珠玑第1章部分课后习题答案注解
- 编程珠玑第2章部分课后习题答案注解
- poj 2429 GCD & LCM Inverse (pollard
- 数据结构之——线性表之顺序表
- 不同页面的tiaozhuan
- git操作命令
- 数据库设计三范式
- Scala函数式编程课后习题答案(第六章)
- QT 中文字符乱码
- C#序列化与反序列化
- 郑桂兰董事长再访日月潭文武庙协天庙佛光大学等台湾地标进行文化交流
- uC/OS-III之任务就绪表学习总结
- Python numpy实现二维数组和一维数组拼接
- 端口号类型
- python之读写excel文件
- 郑桂兰董事长与台湾良机集团董事长张广博商务洽谈