1 | import { equals, pathSatisfies } from 'ramda';
|
---|
2 |
|
---|
3 | import isString from '../isString';
|
---|
4 | import isNumber from '../isNumber';
|
---|
5 | import isFunction from '../isFunction';
|
---|
6 | import { isSameType } from './util';
|
---|
7 | import * as fl from './mapping';
|
---|
8 |
|
---|
9 | export const functorTrait = {
|
---|
10 | [fl.map](fn) {
|
---|
11 | return this.constructor[fl.of](fn(this.value));
|
---|
12 | },
|
---|
13 | };
|
---|
14 |
|
---|
15 | export const applyTrait = {
|
---|
16 | [fl.ap](applyWithFn) {
|
---|
17 | return applyWithFn.map((fn) => fn(this.value));
|
---|
18 | },
|
---|
19 | };
|
---|
20 |
|
---|
21 | export const setoidTrait = {
|
---|
22 | [fl.equals](setoid) {
|
---|
23 | return isSameType(this, setoid) && equals(this.value, setoid.value);
|
---|
24 | },
|
---|
25 | };
|
---|
26 |
|
---|
27 | export const semigroupTrait = {
|
---|
28 | [fl.concat](semigroup) {
|
---|
29 | let concatenatedValue = this.value;
|
---|
30 |
|
---|
31 | if (isString(this.value) || isNumber(this.value)) {
|
---|
32 | concatenatedValue = this.value + semigroup.value;
|
---|
33 | } else if (pathSatisfies(isFunction, ['value', fl.concat], this)) {
|
---|
34 | concatenatedValue = this.value[fl.concat](semigroup.value);
|
---|
35 | } else if (pathSatisfies(isFunction, ['value', 'concat'], this)) {
|
---|
36 | concatenatedValue = this.value.concat(semigroup.value);
|
---|
37 | }
|
---|
38 |
|
---|
39 | return this.constructor[fl.of](concatenatedValue);
|
---|
40 | },
|
---|
41 | };
|
---|
42 |
|
---|
43 | export const chainTrait = {
|
---|
44 | [fl.chain](fn) {
|
---|
45 | const newChain = fn(this.value);
|
---|
46 |
|
---|
47 | return isSameType(this, newChain) ? newChain : this;
|
---|
48 | },
|
---|
49 | };
|
---|
50 |
|
---|
51 | export const ordTrait = {
|
---|
52 | [fl.lte](ord) {
|
---|
53 | return (
|
---|
54 | isSameType(this, ord) && (this.value < ord.value || this[fl.equals](ord))
|
---|
55 | );
|
---|
56 | },
|
---|
57 | };
|
---|