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的更多相关文章

  1. LCG(linear congruential generator): 一种简单的随机数生成算法

    目录 LCG算法 python 实现 LCG算法 LCG(linear congruential generator)线性同余算法,是一个古老的产生随机数的算法.由以下参数组成: 参数 m a c X ...

  2. Beginning Scala study note(4) Functional Programming in Scala

    1. Functional programming treats computation as the evaluation of mathematical and avoids state and ...

  3. 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 ...

  4. 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 ...

  5. Monad (functional programming)

    In functional programming, a monad is a design pattern that defines how functions, actions, inputs, ...

  6. Functional Programming without Lambda - Part 2 Lifting, Functor, Monad

    Lifting Now, let's review map from another perspective. map :: (T -> R) -> [T] -> [R] accep ...

  7. 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 ...

  8. Functional programming

    In computer science, functional programming is a programming paradigm, a style of building the struc ...

  9. Java 中的函数式编程(Functional Programming):Lambda 初识

    Java 8 发布带来的一个主要特性就是对函数式编程的支持. 而 Lambda 表达式就是一个新的并且很重要的一个概念. 它提供了一个简单并且很简洁的编码方式. 首先从几个简单的 Lambda 表达式 ...

随机推荐

  1. hdu 3949 第k大异或组合

    题意: 给你一些数,其中任选一些数(大于等于一个),那么他们有一个异或和. 求所有这样的异或和的第k小. 我们可以将每一位看成一维,然后就是给我们n个60维的向量,求它们线性组合后得到的向量空间中,第 ...

  2. python开发_函数的参数传递

    在这个用例中,我们要讨论的是关于函数的传参问题 我所使用的python版本为3.3.2 对于函数: def fun(arg): print(arg) def main(): fun('hello,Ho ...

  3. poj 2623 Sequence Median 堆的灵活运用

    I - Sequence Median Time Limit:1000MS     Memory Limit:1024KB     64bit IO Format:%I64d & %I64u ...

  4. git pull的时候出错: Git Couldn't reserve space for cygwin's heap

    具体: 1. 运行CMD,以管理员身份打开 2. 运行:rebase.exe -b 0x50000000 msys-1.0.dll 再次git pull的时候,不再报错 转自:http://doc.o ...

  5. ThinkPHP实现登录限制时__construct和_initialize的区别

    ThinkPHP支持两种构造方法:  __construct和_initialize(ThinkPHP内置的构造方法). 测试URL为:  http://oa.com/index.php/Admin/ ...

  6. as 汇编器

    [root@localhost ~]# cat .s .file "write.s" .section .rodata hello: .string "hello, wo ...

  7. POJ 1458 Common Subsequence(最长公共子序列LCS)

    POJ1458 Common Subsequence(最长公共子序列LCS) http://poj.org/problem?id=1458 题意: 给你两个字符串, 要你求出两个字符串的最长公共子序列 ...

  8. Xcode GDB 调试

    关于GDB 对于大多数Cocoa程序员来说,最常用的debugger莫过于Xcode自带的调试工具了.而实际上,它正是gdb的一个图形化包装.相对于gdb,图形化带来了很多便利,但同时也缺少了一些重要 ...

  9. no scheme 问题

    用xcode4打开xcode3建立的工程,有时候,不能自动转换版本,就会显示no scheme. 这个是由于XXX..xcodeproj包中xcuserdata文件夹中user.xcuserdatad ...

  10. python接口自动化4-绕过验证码登录(cookie)

    前言 有些登录的接口会有验证码:短信验证码,图形验证码等,这种登录的话验证码参数可以从后台获取的(或者查数据库最直接). 获取不到也没关系,可以通过添加cookie的方式绕过验证码. 一.抓登录coo ...