sum-type
Version:
A simple library for complex logic
3 lines (2 loc) • 8.68 kB
JavaScript
const t=(t,...e)=>{if(0==e.length)throw new Error("You must provide an initial value and a non-empty spread of functions.");return e.reduce(((t,e)=>e(t)),t)},e=t=>n=>{if(Array.isArray(n)){const r=n,a=r.filter((e=>!t.includes(e)));if(a.length)throw new Error("Tags provided do not match original definition. The tags: ("+a.join("|")+") could not be found in the list: ("+t.join("|")+")");return e(r)}return t.reduce(((t,e)=>Object.assign(t,{[e]:n})),{})},n=(...e)=>{if(0==e.length)throw new Error("You must provide a non-empty spread of functions.");return n=>t(n,...e)},r=(t,e)=>t>0?((t,e)=>Array(t).fill(e))(t,e).join(""):"";function a(t,e){const n=Object(e)===e,r=null==e,a=n&&Array.isArray(e),i=n&&!a,s=n&&"function"==typeof e,o=!n,c=i&&e.type&&e.tag,u=c&&"value"in e,l=c&&!u;return t({notPrimative:n,isPrimative:o,isString:"string"==typeof e,isNil:r,isArray:a,isObject:i,isPojo:i&&"Object"==e.constructor.name,isDate:i&&e instanceof Date,isError:i&&e instanceof Error,value:e,isFunction:s,isStag:c,valueStag:u,emptyStag:l})}const i=e=>a(function e(n){return i=>{const{value:s,isPojo:o,isObject:c,isArray:u,isDate:l,isError:g,valueStag:f,emptyStag:p,isString:y,isFunction:h}=i,m=r(n,""),d=r(n-1,""),v=r(n+1,""),b="";return f?s.type+"."+s.tag+"("+(void 0===s.value?"":a(e(n+1),s.value))+(n>0?b+d:"")+b+m+")":p?s.type+"."+s.tag+"()":o?0==Object.keys(s).length?"{}":t(s,Object.entries,(t=>t.map((([t,r])=>b+v+'"'+t+'":'+a(e(n+1),r).replace(b+v,"")))),(t=>b+m+"{"+t+b+m+"}")):u?"0"==s.length?"[]":b+m+"["+b+m+m+s.map((t=>a(e(n+1),t))).join(", ")+b+m+"]":l?"new "+s.constructor.name+'("'+s.toISOString()+'")':g?"new "+s.constructor.name+'("'+s.message+'")':h?s+"":c?"new "+s.constructor.name+"()":y?JSON.stringify(s):""+s}}(0),e),s=t=>a((function t({value:e,isPojo:n,isArray:r,valueStag:i,emptyStag:s}){return i?a(t,e.value):s?null:n?p(Object.entries(e).map((e=>a(t,e)))):r?e.map((e=>a(t,e))):e}),t);function o(){return i(this)}function c(t){return t.type}function u(t){return t.tag}const l={toString:o,inspect:o,[Symbol.for("nodejs.util.inspect.custom")]:o};function g(t,e,n){return Object.assign(Object.create(l),{type:t,tag:e,value:n})}function f(t,e){return Object.assign(Object.create(l),{type:t,tag:e})}const p=t=>t.reduce(((t,[e,n])=>({...t,[e]:n})),{}),y=["ExtraTags","MissingTags","InstanceNull","InstanceWrongType","InstanceShapeInvalid","VisitorNotAFunction","NotAType","TagsShapeInvalid"].reduce(((t,e)=>(t[e]=n=>g(t.type,e,n),t.tags.push(e),t)),{type:"StaticSumTypeError",tags:[],traits:{}});function h(t){return t.tags}const m={ExtraTags:function(t){return["Your tag function must have exactly the same"," keys as the type: "+t.T.type+". ","The following tags should not have been present:",t.extraKeys.join(", ")].join(" ")},MissingTags:function(t){},InstanceNull:function(t){return"Null is not a valid member of the type "+t.T.type},InstanceWrongType:function(t){},InstanceShapeInvalid:function(t){return[i(t.x),"is not a valid Member of the type:",t.T.type+". ","Please review the definition of "+t.T.type].join(" ")},VisitorNotAFunction:function(t){return t.context+" expected a visitor function but instead received "+i(t.visitor)},NotAType:function(t){return t.context+" expected a Type ({ type: string, tags: string[] }) but received "+i(t.T)},TagsShapeInvalid:(t,e)=>"fold("+c(t)+") tags provided were not the right shape. Expected { [tag]: f } but received "+i(e)};function d(t){const e=t();return N("fold",e),function(t){!function(t,e){if(null==e||Array.isArray(e)||"object"!=typeof e){return b(T.TagsShapeInvalid(t,e))}}(e,t);const n=Object.keys(t),r=h(e),a=[[n,e],[r,t]].map((function(t){const e=t[0],n=t[1];return e.filter((function(t){return!(t in n)}))})),i=a[0],s=a[1];return s.length>0?b(T.MissingTags({T:e,tags:t,missingKeys:s})):i.length>0?b(T.ExtraTags({T:e,tags:t,extraKeys:i})):function(n){return O(e,t,n)&&t[u(n)](n.value)}}}const v=t=>{return(e=m,t=>e[t.tag](t.value))(t);var e};function b(t){throw new Error(u(t)+": "+v(t))}const T=y;function N(t,e){return null!=e&&null!=e&&"string"==typeof e.type&&Array.isArray(e.tags)&&"traits"in e?null:b(T.NotAType({context:t,T:e}))}function j(t){return"function"!=typeof t.visitor?b(T.VisitorNotAFunction({context:t.context,visitor:t.visitor})):null}function x(t,e){return null!=e&&c(e)==t.type&&h(t).includes(u(e))?null:b(T.InstanceShapeInvalid({x:e,T:t}))}function O(t,e,n){return null==n?b(T.InstanceNull({T:t,tags:e,x:n})):c(n)!==t.type?b(T.InstanceWrongType({T:t,tags:e,x:n})):!!h(t).includes(u(n))||b(T.InstanceShapeInvalid({T:t,tags:e,x:n}))}function S(t){return d((()=>t))}const A=t=>{const e=S(t);return n=>{const r=e(n);return e=>{x(t,e);const n=r(e);return t[u(e)](n)}}},I=t=>{const e=S(t);return n=>{const r=e(n);return e=>{if(O(t,n,e),"value"in e){const a=r(e);return O(t,n,a)&&a}return e}}},E=(t,e)=>({type:t,traits:{},tags:e,...p(e.map((e=>[e,(...n)=>n.length?g(t,e,n[0]):f(t,e)])))});function Y(t){return E(t,["Y","N"])}const w=Y("sumType.Either"),W=t=>{const e=S(t),{left:n,right:r}=t.traits["sum-type/bifunctor"];return(t,a)=>e({[n]:t,[r]:a})},B=t=>(N("bifold",t),W(t)),P=t=>(N("bimap",t),(t=>{const e=A(t),{left:n,right:r}=t.traits["sum-type/bifunctor"];return(t,a)=>e({[n]:t,[r]:a})})(t)),F=t=>(N("getOr",t),e=>n=>(x(t,n),(t=>e=>W(t)((()=>e),(t=>t)))(t)(e)(n))),M=t=>(N("concatWith",t),e=>(j({context:"concatWith",visitor:e}),n=>(x(t,n),r=>(x(t,r),(t=>e=>n=>r=>{const{left:a,right:i}=t.traits["sum-type/bifunctor"];return u(n)==a?n:u(r)==a?r:t[i](e(n.value)(r.value))})(t)(e)(n)(r))))),k=({left:t,right:e})=>n=>(n.traits["sum-type/bifunctor"]={left:t,right:e},n.left=e=>n[t](e),n.right=t=>n[e](t),n.bifold=B(n),n.bimap=P(n),n.getOr=F(n),n.getWith=(t=>(e,n)=>B(t)((()=>e),(t=>n(t))))(n),n.tagBy=(t=>(S(t),(e,n)=>r=>(j({context:"tagBy",visitor:n}),n(r)?t.right(r):t.left(e))))(n),n.encase=(t=>e=>n=>{try{return t.right(e(n))}catch(e){return t.left(e)}})(n),n.toBoolean=(t=>t.bifold((()=>!1),(()=>!0)))(n),n.fromNullable=(t=>e=>null==e?t.left(e):t.right(e))(n),n.all=(t=>e=>{const n=e.filter((e=>!t.toBoolean(e)));return n.length>0?t.left(n.map((t=>t.value))):t.right(e.map(t.getOr(null)))})(n),n.any=(t=>e=>e.some(t.toBoolean)?t.right(e.filter(t.toBoolean).map(t.getOr(null))):e.find((e=>!t.toBoolean(e))))(n),n.concatWith=M(n),n);function D(t){if(t.traits["sum-type/decorated"])return t;{const n=e(h(t)),r=A(t),a=I(t),i=S(t);return h(t).forEach((e=>{[[e,e,e],[e,"_"+e,"_"+e+"_"]].forEach((([e,s,o])=>{t["is"+s]=t["is"+s]||(n=>(x(t,n),u(n)===e)),t["map"+s]=t["map"+s]||(t=>r({...n((t=>t)),[e]:t})),t["get"+o+"Or"]=t["get"+o+"Or"]||(t=>i({...n((()=>t)),[e]:t=>t})),t["get"+o+"With"]=t["get"+o+"With"]||((t,r)=>i({...n((()=>t)),[e]:t=>r(t)})),t["chain"+s]=t["chain"+s]||(t=>r=>a({...n((()=>r)),[e]:t})(r)),t["assert"+s]=t["assert"+s]||i({...n(w.N),[e]:w.Y}),t[e.toLowerCase()+"s"]=t[e+"s"]||(n=>n.reduce(((n,r)=>n.concat(t["is"+e](r)?[r.value]:[])),[]))}))})),t.fold=t.fold||i,t.mapAll=t.mapAll||r,t.chainAll=t.chainAll||a,t.traits["sum-type/decorated"]=!0,t}}const K=n=>{return t(Y(n),D,k({left:"N",right:"Y"}),(r="Y",t=>(t.traits["sum-type/functor"]=r,t.of=t[r],t.map=t.map||(n=>(j({context:"map",visitor:n}),A(t)({...e(t.tags)((t=>t)),[r]:n}))),t)),(t=>n=>{n.traits["sum-type/monad"]=t,n.of=n[t];const r=I(n);return n.chain=a=>(j({context:"chain",visitor:a}),i=>r({...e(n.tags)((t=>n[u(i)](t))),[t]:t=>a(t)})(i)),n})("Y"));var r},V=e=>t(e,K,(t=>{const e=t.N;return t.N=()=>e(),t.traits["sum-type/maybe"]=!0,t})),_=(t,e)=>D(E(t,e)),C=K("sumType.Either"),{Y:J,N:L,bifold:q,getOr:z,getWith:G,bimap:H,map:Q,mapY:R,mapN:U,assertY:X,assertN:Z,chainN:$,chainY:tt,tagBy:et,chain:nt,toBoolean:rt,encase:at,fromNullable:it,all:st,any:ot,isY:ct,isN:ut,ys:lt,ns:gt,concatWith:ft}=C,pt=it;export{st as Eall,ot as Eany,Z as EassertN,X as EassertY,q as Ebifold,H as Ebimap,nt as Echain,$ as EchainN,tt as EchainY,ft as EconcatWith,at as Eencase,it as EfromNullable,z as EgetOr,G as EgetWith,ut as EisN,ct as EisY,C as Either,Q as Emap,U as EmapN,R as EmapY,gt as Ens,et as EtagBy,rt as EtoBoolean,lt as Eys,L as N,y as StaticSumTypeError,J as Y,st as all,ot as any,Z as assertN,X as assertY,q as bifold,H as bimap,o as boundToString,nt as chain,I as chainAll,$ as chainN,tt as chainY,ft as concatWith,D as decorate,C as decoratedEither,K as either,f as emptyInstance,at as encase,v as errMessage,K as externalEither,V as externalMaybe,_ as externalTags,S as fold,pt as fromNullable,z as getOr,h as getTags,G as getWith,ut as isN,ct as isY,Q as map,A as mapAll,U as mapN,R as mapY,V as maybe,gt as ns,e as otherwise,n as pipe,t as run,et as tagBy,u as tagName,_ as tags,rt as toBoolean,s as toJSON,i as toString,c as typeName,g as valueInstance,lt as ys};
//# sourceMappingURL=sum-type.esm.min.js.map