文档章节

[Functional Programming] Running though a serial number prediction functions for tagging, pairing...

o
 osc_n6euf5h6
发布于 2019/03/19 21:11
字数 843
阅读 16
收藏 0

精选30+云产品,助力企业轻松上云!>>>

Let's we have some prediction functions, for each prediction function has a corresponding tag:

const {gt, lte, gte, lt} = require('ramda');
const {flip} = require('crocks');

const getSmlPred = and(flip(gt, -1), flip(lte, 50));
const getMedPred = and(flip(gt, 50), flip(lte, 100));
const getLrgPred =  flip(gt, 100);
// taggedPred :: (b, (a -> Boolean))
// taggedPreds :: [taggedPred]
const taggedPreds = [
    ['Sml', getSmlPred],
    ['Med', getMedPred],
    ['Lrg', getLrgPred]
];

So if we have input as:

15 -> 'Sml';
60 -> 'Med'
101 -> 'Lrg'

Also we wish our program to the safe, we want:

-1 -> Nothing

 

We can write a quick test function:

const {gt, lte, gte, lt} = require('ramda');

const {First, mreduceMap, and, safe, option, flip, objOf, assoc, not,
    merge, identity, fanout, curry, compose, map, constant} = require('crocks');


const getSmlPred = and(flip(gt, -1), flip(lte, 50));
const getMedPred = and(flip(gt, 50), flip(lte, 100));
const getLrgred =  flip(gt, 50);
// taggedPred :: (b, (a -> Boolean))
// taggedPreds :: [taggedPred]
const taggedPreds = [
    ['Sml', getSmlPred],
    ['Med', getMedPred],
    ['Lrg', getLrgred]
];

const fn = curry(([tag, pred]) => x => safe(pred)(x)
    .map(constant(tag)));

console.log('40 - Sml', fn(taggedPreds[0], 40)); // Just "Sml"
console.log('60 - Med', fn(taggedPreds[1], 60)); // Just "Med"
console.log('101 - Lrg', fn(taggedPreds[2], 101)); // Just "Lrg"

  

We can refactor the code into a more pointfree style and rename the testing 'fn' to 'tagValue':

const {gt, lte, gte, lt} = require('ramda');

const {First, mreduceMap, and, safe, option, flip, objOf, assoc, not,
    merge, identity, fanout, curry, compose, map, constant} = require('crocks');


const getSmlPred = and(flip(gt, -1), flip(lte, 50));
const getMedPred = and(flip(gt, 50), flip(lte, 100));
const getLrgred =  flip(gt, 50);
// taggedPred :: (b, (a -> Boolean))
// taggedPreds :: [taggedPred]
const taggedPreds = [
    ['Sml', getSmlPred],
    ['Med', getMedPred],
    ['Lrg', getLrgred]
];
// tagValue :: taggedPred -> a -> Maybe b
const tagValue = curry(([tag, pred]) => compose(
    map(constant(tag)),
    safe(pred)
));    

console.log('40 - Sml', tagValue(taggedPreds[0], 40)); // Just "Sml"
console.log('60 - Med', tagValue(taggedPreds[1], 60)); // Just "Med"
console.log('101 - Lrg', tagValue(taggedPreds[2], 101)); // Just "Lrg"
console.log('-1 - Nothing', tagValue(taggedPreds[0], -5)); // Nothing "Nothing"

 

Now, what we want is create fews functions, we know that we want data comes last, we want to partiaclly apply the predcitions functions.

// match :: [ taggedPreds ] -> a -> Maybe b
const match = 
    flip(x => mreduceMap(First, flip(tagValue, x)));  
const matchNumber = match(taggedPreds);
console.log('matchNumber', matchNumber(49)); // Just "Sml"

'mreduceMap': it take Monoid for combine the data together, here we use 'First', so only take the first Maybe result. 

Then for each [tag, pred], we will run with tagValue([tag, pred], x), because [tag, pred] will be partiaclly applied last, but 'tagValue' function takes it as first arguement, so we have to use 'flip'. And apply 'x' first.

In the test code above, we get ''Just Sml" back for number 49. It is good, but not enough, what we really want is keeping a Pair(a, s), for example: Pair('Sml', 40); we can keep the original state together with the tag result. 

 

What we can do is using 'fanout', which take two functions and generate a Pair:

const tagCard = fanout(compose(option(' | '), matchNumber), objOf('number'));
console.log('tagCard', tagCard(49)); // Pair( "Sml", { number: 49 } )

 

Lastly, we want to have the final result as:

const cardFromNumber = compose(
    merge(assoc('type')),
    tagCard
);

console.log(
    cardFromNumber(101)
) // { number: 101, type: 'Lrg' }

 

Full Code:

---

const {gt, lte} = require('ramda');

const {First, mreduceMap, and, safe, option, flip, objOf, assoc,
    merge, fanout, curry, compose, map, constant} = require('crocks');


const getSmlPred = and(flip(gt, -1), flip(lte, 50));
const getMedPred = and(flip(gt, 50), flip(lte, 100));
const getLrgred =  flip(gt, 100);
// taggedPred :: (b, (a -> Boolean))
// taggedPreds :: [taggedPred]
const taggedPreds = [
    ['Sml', getSmlPred],
    ['Med', getMedPred],
    ['Lrg', getLrgred]
];

// tagValue :: taggedPred -> a -> Maybe b
const tagValue = curry(([tag, pred]) => compose(
    map(constant(tag)),
    safe(pred)
));    

// match :: [ taggedPreds ] -> a -> Maybe b
const match = 
    flip(x => mreduceMap(First, flip(tagValue, x)));  
const matchNumber = match(taggedPreds);

const tagCard = fanout(compose(option(' | '), matchNumber), objOf('number'));

const cardFromNumber = compose(
    merge(assoc('type')),
    tagCard
)

console.log(
    cardFromNumber(101)
) // { number: 101, type: 'Lrg' }

 

---

This coding partten is useful, because we can keep the structure, just replace the tags and predications functions:

// data.js
const {test} = require('ramda');

module.exports = [
    ['Diners - Carte Blanche|diners', test(/^30[0-5]/)],
    ['Diners|diners', test(/^(30[6-9]|36|38)/)],
    ['JCB|jcb', test(/^32(2[89]|[3-8][0-9])/)],
    ['AMEX|american-express', test(/^3[47]/)],
    ['Visa Electron|visa', test(/^(4026|417500|4508|4844|491(3|7))/)]
]
const {gt, lte} = require('ramda');

const {First, mreduceMap, and, safe, option, flip, objOf, assoc,
    merge, fanout, curry, compose, map, constant} = require('crocks');


const getSmlPred = and(flip(gt, -1), flip(lte, 50));
const getMedPred = and(flip(gt, 50), flip(lte, 100));
const getLrgred =  flip(gt, 100);
// taggedPred :: (b, (a -> Boolean))
// taggedPreds :: [taggedPred]
const taggedPreds = require('./data.js');
// tagValue :: taggedPred -> a -> Maybe b
const tagValue = curry(([tag, pred]) => compose(
    map(constant(tag)),
    safe(pred)
));    

// match :: [ taggedPreds ] -> a -> Maybe b
const match = 
    flip(x => mreduceMap(First, flip(tagValue, x)));  
const matchNumber = match(taggedPreds);

const tagCard = fanout(compose(option(' | '), matchNumber), objOf('number'));

const cardFromNumber = compose(
    merge(assoc('type')),
    tagCard
)

console.log(
    cardFromNumber('4026-xxxx-xxxxx-xxxx')
) // { number: '4026-xxxx-xxxxx-xxxx', type: 'Visa Electron|visa' }

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
Tagging recommendations for SAP on AWS

https://amazonaws-china.com/blogs/awsforsap/tagging-recommendations-for-sap-on-aws/ Customers running SAP on AWS often ask us if we’ve seen reusable trends in tagging strategi......

osc_ao91jbnq
03/19
1
0
从C++和OCaml程序员的视角看Rust (Part 1)

本文来源地址 SEPTEMBER 5, 2017 by GUILLAUME ENDIGNOUX @GEndignoux This summer, I decided to have a look at Rust, the new programming language that everyone is talking about. Rus......

朱小虎XiaohuZhu
2019/06/04
0
0
Tagging recommendations for SAP on AWS

https://amazonaws-china.com/blogs/awsforsap/tagging-recommendations-for-sap-on-aws/ Customers running SAP on AWS often ask us if we’ve seen reusable trends in tagging strategi......

osc_5h5udyht
03/19
2
0
如何 group by time, 我这个代码总出错

这个链接 http://ec2-52-40-164-217.us-west-2.compute.amazonaws.com:3000/api/datasources/proxy/1/query?db=telegraf&q=SELECT near_failure as "Disk Health Status", disk_serial_numbe......

Benny_Luo
2017/11/30
158
1
Step-by-Step Guide to Implement Machine Learning V - Support Vector Machine

Introduction Support Vector Machine(SVM) is a classifier based on the max margin in feature space. The learning strategy of SVM is to make the margin max, which can be transform......

danc1elion
2019/05/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

R中“ =”和“ <-”赋值运算符有什么区别?

问题: What are the differences between the assignment operators = and <- in R? R中赋值运算符=和<-之间有什么区别? I know that operators are slightly different, as this example ......

fyin1314
32分钟前
14
0
JavaScript中的静态变量 - Static variables in JavaScript

问题: 如何在Javascript中创建静态变量? 解决方案: 参考一: https://stackoom.com/question/6RUF/JavaScript中的静态变量 参考二: https://oldbug.net/q/6RUF/Static-variables-in-Java...

法国红酒甜
今天
14
0
之间的区别 和

问题: I'm learning Spring 3 and I don't seem to grasp the functionality behind <context:annotation-config> and <context:component-scan> . 我正在学习Spring 3,并且似乎不太了解<......

javail
今天
15
0
业内首款,百度工业视觉智能平台全新亮相

本文作者:y****n 业内首款全国产化工业视觉智能平台——百度工业视觉智能平台亮相中国机器视觉展(Vision China),该平台所具有的核心AI能力完全自主可控,在质检、巡检等场景中具有高效、...

百度开发者中心
昨天
7
0
我们如何制作xkcd样式图? - How can we make xkcd style graphs?

问题: Apparently, folk have figured out how to make xkcd style graphs in Mathematica and in LaTeX . 显然,民间已经想出了如何在Mathematica和LaTeX中制作xkcd风格的图形。 Can we d......

富含淀粉
今天
10
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部