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
原创粉丝点击