[Functional Programming] Build a Linear congruential generator
What we are going to do in this post, is to build a random number generator. As you might know that Javascript provides Math.random(), but the problem for Math.random() is you cannot control it, what we actully want is a number generator which can provide the same sequence of random numbers. Imaging we have a game, everytime we start the game it will genarte
[5,7,9,8,1,3....]
Second times, it runs the game, it produce the same output: [5,7,9,8,1,3....]. This kind of number generator is called: Linear congruential generator
We are going to use 'crocks/State' to coding it:
const log = require('./lib/log');
const State = require('crocks/State');
const B = require('crocks/combinators/composeB');
const K = require('crocks/combinators/constant');
const prop = require('crocks/Maybe/prop');
const option = require('crocks/pointfree/option');
const {modify, get} = State;
const assign = require('crocks/helpers/assign');
// pluckSeed :: Integer -> Object -> Integer
const pluckSeed =
def => B(option(def), prop('seed'))
// rando : Integer -> State Object Float
const rando = x => {
const seed = (1103515245 * x + 12345) & 0x7fffffff
const value = (seed >>> 16) / 0x7fff;
return modify(assign({seed})) // update the seed Pair(_, seed)
.map(K(value)); // update the value Pair(value, seed)
}
// pullRandom :: Integer -> State Object Float
const pullRandom =
defSeed => get(pluckSeed(defSeed)).chain(rando);
// limitIndx :: Integer -> Float -> Integer
const limitIndx = len => x => (x * len) | 0;
const seed = 76;
log(
State.of(seed)
.chain(pullRandom) // 'Pair( 0.13864558854945525, { seed: 297746555 } )'
.map(limitIndx(52)) // 'Pair( 7, { seed: 297746555 } )'
.runWith({seed: 10})
);
Let's explain some operator a little bit:
const B = require('crocks/combinators/composeB');
'composeB', the same as 'compose' read from right to left, the only difference is it only accepts two functions! no more no less.
// pluckSeed :: Integer -> Object -> Integer
const pluckSeed =
def => B(option(def), prop('seed'))
'pluckSeed', we use 'prop' from 'Maybe', to get value from Maybe, we need to use 'option', if Maybe returns Nothing, then we use the default value from 'option(def)'.
const State = require('crocks/State');
const {modify, get} = State;
// rando : Integer -> State Object Float
const rando = x => {
const seed = (1103515245 * x + 12345) & 0x7fffffff
const value = (seed >>> 16) / 0x7fff;
return modify(assign({seed})) // update the seed Pair(_, seed)
.map(K(value)); // update the value Pair(value, seed)
}
'modify' it a constructor' method for 'State' moand, the State monad is constructed by Pair moand:
State(Pair(a, s))
On the left side, 'a' is the new state which come from 's' after mapping to some function. 's' is the origianl state.
When you call 'modify', it is actually modifying the right side 's':
modify(assign({seed})) // update the seed Pair(_, seed)
When you call .map(fn), it is change the value on the left side of Pair:
return modify(assign({seed})) // update the seed Pair(_, seed)
.map(constant(value)); // update the value Pair(value, seed)
[Functional Programming] Build a Linear congruential generator的更多相关文章
- LCG(linear congruential generator): 一种简单的随机数生成算法
目录 LCG算法 python 实现 LCG算法 LCG(linear congruential generator)线性同余算法,是一个古老的产生随机数的算法.由以下参数组成: 参数 m a c X ...
- Beginning Scala study note(4) Functional Programming in Scala
1. Functional programming treats computation as the evaluation of mathematical and avoids state and ...
- a primary example for Functional programming in javascript
background In pursuit of a real-world application, let’s say we need an e-commerce web applicationfo ...
- BETTER SUPPORT FOR FUNCTIONAL PROGRAMMING IN ANGULAR 2
In this blog post I will talk about the changes coming in Angular 2 that will improve its support fo ...
- Monad (functional programming)
In functional programming, a monad is a design pattern that defines how functions, actions, inputs, ...
- Functional Programming without Lambda - Part 2 Lifting, Functor, Monad
Lifting Now, let's review map from another perspective. map :: (T -> R) -> [T] -> [R] accep ...
- Functional Programming without Lambda - Part 1 Functional Composition
Functions in Java Prior to the introduction of Lambda Expressions feature in version 8, Java had lon ...
- Functional programming
In computer science, functional programming is a programming paradigm, a style of building the struc ...
- Java 中的函数式编程(Functional Programming):Lambda 初识
Java 8 发布带来的一个主要特性就是对函数式编程的支持. 而 Lambda 表达式就是一个新的并且很重要的一个概念. 它提供了一个简单并且很简洁的编码方式. 首先从几个简单的 Lambda 表达式 ...
随机推荐
- HDU 5714 拍照 前缀和
拍照 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5714 Description 小明在旅游的路上看到了一条美丽的河,河上有许多船只,有的船只向左 ...
- SDWebImage支持WebP格式图片
SDWebImage本身就已经支持了webp格式的图片 1.下载libwebp https://github.com/webmproject/libwebp 然后你需要先安装好有homebrew或者m ...
- Linux知识(7)----远程登录 和远程拷贝
一.远程登录 1.安装客户端 可以使用ssh(Secure Shell(缩写为SSH))来进行远程的登录.安装ssh的命令为: sudo apt-get install openssh-server ...
- git中如何合并某个指定文件?
分支A_bracn和B_branch,只想将A_branch分支的某个文件f.txt合并到B_branch分支上.git checkout A_branch git checkout --p ...
- 五子棋游戏 canvas 事件 边界检测
//有一定基础的人才能看得懂 <!doctype html><html lang="en"> <head> <meta charset=& ...
- 忘记Oracle系统管理员sys的密码
sqlplus / as sysdba; alter user sys identified by newpwd***;
- SEEprog Serial EEPROM programmer
Features SEEprog is universal programmer of all types of serial EEPROMs in 8-pin package. SEEprog en ...
- C#中,什么时候用yield return
yield关键字用于遍历循环中,yield return用于返回IEnumerable<T>,yield break用于终止循环遍历. 有这样的一个int类型的集合: static Lis ...
- 报错:无法从int?转换为int
□ 背景分析 在控制器方法中的一个参数允许为null值:public ActionResult GetByCategory(int? categoryId = null) 当把这里的categoryI ...
- eclipse svn最新更新地址
http://subclipse.tigris.org/update_1.12.x http://subclipse.tigris.org/servlets/ProjectProcess?pageID ...