├── .gitignore ├── .vscode └── tasks.json ├── CONTRIBUTE.md ├── LICENSE ├── README.md ├── assets ├── analytics.js └── highlight │ ├── atom-one-dark.css │ ├── highlight.pack.js │ ├── monokai-sublime.css │ ├── railscasts.css │ └── solarized-dark.css ├── available-languages.json ├── concepts.json ├── demo.png ├── docs ├── app-482d3dffb1fc377007d6 ├── assets │ ├── analytics.js │ └── highlight │ │ ├── highlight.pack.js │ │ └── solarized-dark.css ├── available-languages.json ├── concepts.json ├── favicon.ico ├── images │ └── elm.png └── index.html ├── elm-package.json ├── images └── elm.png ├── package.json ├── src ├── CustomPorts.elm ├── Decoders.elm ├── Main.elm ├── Pages │ ├── About │ │ └── About.elm │ └── Babelfish │ │ ├── Babelfish.elm │ │ ├── Helpers.elm │ │ ├── Messages.elm │ │ ├── ViewConceptMatrix.elm │ │ └── ViewFullConcepts.elm ├── Routing │ ├── Helpers.elm │ └── Router.elm ├── Types.elm ├── favicon.ico ├── index.html ├── index.js ├── index_prod.html └── main.css ├── tests ├── Example.elm └── elm-package.json ├── webpack.config.js └── webpack.config.prod.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Distribution 2 | dist/ 3 | 4 | # elm-package generated files 5 | elm-stuff 6 | 7 | # elm-repl generated files 8 | repl-temp-* 9 | 10 | # Dependency directories 11 | node_modules 12 | 13 | # Desktop Services Store on macOS 14 | .DS_Store 15 | /elm.js 16 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.1.0", 3 | "tasks": [ 4 | { 5 | "taskName": "npm start", 6 | "command": "npm", 7 | "isShellCommand": true, 8 | "args": ["start"], 9 | "showOutput": "always" 10 | }, 11 | { 12 | "taskName": "npm build", 13 | "command": "npm", 14 | "args": ["run", "build"], 15 | "isBuildCommand": true, 16 | "isShellCommand": true, 17 | "showOutput": "always" 18 | }, 19 | { 20 | "taskName": "elm-test", 21 | "command": "elm-test", 22 | "args": [], 23 | "isTestCommand": true, 24 | "isShellCommand": true, 25 | "showOutput": "always" 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /CONTRIBUTE.md: -------------------------------------------------------------------------------- 1 | # Contribution guidelines 2 | 3 | Please contribute with any corrections, improvements and other languages. It's also possible to add other concepts. PR's and issues are welcome. 4 | 5 | #### How to edit concepts and languages - structure 6 | There are two separate files 7 | * available-languages.json 8 | * This file contains the available languages and their highlight code. Any language here will be available, but only the first 4 is viewed initially (user can select in headers) 9 | * concepts.json 10 | * Contains the concepts, notes, links and language implementations with examples. 11 | * Adding a new language here will also require a new language in available-languages.json 12 | * New concept can be added. 13 | 14 | #### Running on your local machine 15 | ##### With Elm installed 16 | [Install Elm here](https://elm-lang.org) 17 | 18 | ```Clone repo and use npm start to run development. Use npm run build for production."``` 19 | 20 | ##### Without Elm installed 21 | ```Clone repo and use a nodejs http server like http-server to run inside the "docs folder. Copy the .json files to root when finished."``` 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2017 Håkon Rossebø 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [Functional programming babelfish](https://hakonrossebo.github.io/functional-programming-babelfish/) 2 | 3 | ## [Site is located on Github pages here](https://hakonrossebo.github.io/functional-programming-babelfish/) 4 | Please [contribute](CONTRIBUTE.md) with PR's and issues to help improve this reference. 5 | Any new languages would be very helpful. 6 | 7 | [](https://hakonrossebo.github.io/functional-programming-babelfish/) 8 | 9 | This is an attempt to provide a link and comparison between similar concepts and operations and their usage between different functional programming languages . When learning and working with different languages and concepts, it's nice to have an easy way of looking up the implementations. Please contribute! I am not an expert in these languages. Please contribute to improvements with PR's and issues to help improve this reference. 10 | -------------------------------------------------------------------------------- /assets/analytics.js: -------------------------------------------------------------------------------- 1 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 2 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 3 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 4 | })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 5 | 6 | ga('create', 'UA-92960408-1', 'auto'); 7 | ga('send', 'pageview'); 8 | -------------------------------------------------------------------------------- /assets/highlight/atom-one-dark.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Atom One Dark by Daniel Gamage 4 | Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax 5 | 6 | base: #282c34 7 | mono-1: #abb2bf 8 | mono-2: #818896 9 | mono-3: #5c6370 10 | hue-1: #56b6c2 11 | hue-2: #61aeee 12 | hue-3: #c678dd 13 | hue-4: #98c379 14 | hue-5: #e06c75 15 | hue-5-2: #be5046 16 | hue-6: #d19a66 17 | hue-6-2: #e6c07b 18 | 19 | */ 20 | 21 | .hljs { 22 | display: block; 23 | overflow-x: auto; 24 | padding: 0.5em; 25 | color: #abb2bf; 26 | background: #282c34; 27 | } 28 | 29 | .hljs-comment, 30 | .hljs-quote { 31 | color: #5c6370; 32 | font-style: italic; 33 | } 34 | 35 | .hljs-doctag, 36 | .hljs-keyword, 37 | .hljs-formula { 38 | color: #c678dd; 39 | } 40 | 41 | .hljs-section, 42 | .hljs-name, 43 | .hljs-selector-tag, 44 | .hljs-deletion, 45 | .hljs-subst { 46 | color: #e06c75; 47 | } 48 | 49 | .hljs-literal { 50 | color: #56b6c2; 51 | } 52 | 53 | .hljs-string, 54 | .hljs-regexp, 55 | .hljs-addition, 56 | .hljs-attribute, 57 | .hljs-meta-string { 58 | color: #98c379; 59 | } 60 | 61 | .hljs-built_in, 62 | .hljs-class .hljs-title { 63 | color: #e6c07b; 64 | } 65 | 66 | .hljs-attr, 67 | .hljs-variable, 68 | .hljs-template-variable, 69 | .hljs-type, 70 | .hljs-selector-class, 71 | .hljs-selector-attr, 72 | .hljs-selector-pseudo, 73 | .hljs-number { 74 | color: #d19a66; 75 | } 76 | 77 | .hljs-symbol, 78 | .hljs-bullet, 79 | .hljs-link, 80 | .hljs-meta, 81 | .hljs-selector-id, 82 | .hljs-title { 83 | color: #61aeee; 84 | } 85 | 86 | .hljs-emphasis { 87 | font-style: italic; 88 | } 89 | 90 | .hljs-strong { 91 | font-weight: bold; 92 | } 93 | 94 | .hljs-link { 95 | text-decoration: underline; 96 | } 97 | -------------------------------------------------------------------------------- /assets/highlight/highlight.pack.js: -------------------------------------------------------------------------------- 1 | /*! highlight.js v9.9.0 | BSD3 License | git.io/hljslicense */ 2 | !function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/[&<>]/gm,function(e){return I[e]})}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function i(e){return k.test(e)}function a(e){var n,t,r,a,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return R(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(a=o[n],i(a)||R(a))return a}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,i){for(var a=e.firstChild;a;a=a.nextSibling)3===a.nodeType?i+=a.nodeValue.length:1===a.nodeType&&(n.push({event:"start",offset:i,node:a}),i=r(a,i),t(a).match(/br|hr|img|input/)||n.push({event:"stop",offset:i,node:a}));return i}(e,0),n}function c(e,r,i){function a(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){l+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=a();if(l+=n(i.substring(s,g[0].offset)),s=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=a();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(i.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(i,a){if(!i.compiled){if(i.compiled=!0,i.k=i.k||i.bK,i.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof i.k?c("keyword",i.k):E(i.k).forEach(function(e){c(e,i.k[e])}),i.k=u}i.lR=t(i.l||/\w+/,!0),a&&(i.bK&&(i.b="\\b("+i.bK.split(" ").join("|")+")\\b"),i.b||(i.b=/\B|\b/),i.bR=t(i.b),i.e||i.eW||(i.e=/\B|\b/),i.e&&(i.eR=t(i.e)),i.tE=n(i.e)||"",i.eW&&a.tE&&(i.tE+=(i.e?"|":"")+a.tE)),i.i&&(i.iR=t(i.i)),null==i.r&&(i.r=1),i.c||(i.c=[]);var s=[];i.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"===e?i:e)}),i.c=s,i.c.forEach(function(e){r(e,i)}),i.starts&&r(i.starts,a);var l=i.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([i.tE,i.i]).map(n).filter(Boolean);i.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,i,a){function o(e,n){var t,i;for(t=0,i=n.c.length;i>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!i&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var i=r?"":y.classPrefix,a='',a+n+o}function p(){var e,t,r,i;if(!E.k)return n(B);for(i="",t=0,E.lR.lastIndex=0,r=E.lR.exec(B);r;)i+=n(B.substring(t,r.index)),e=g(E,r),e?(M+=e[1],i+=h(e[0],n(r[0]))):i+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(B);return i+n(B.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!x[E.sL])return n(B);var t=e?l(E.sL,B,!0,L[E.sL]):f(B,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(L[E.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){k+=null!=E.sL?d():p(),B=""}function v(e){k+=e.cN?h(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(B+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?B+=n:(t.eB&&(B+=n),b(),t.rB||t.eB||(B=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var i=E;i.skip?B+=n:(i.rE||i.eE||(B+=n),b(),i.eE&&(B=n));do E.cN&&(k+=C),E.skip||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),i.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return B+=n,n.length||1}var N=R(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,E=a||N,L={},k="";for(w=E;w!==N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var B="",M=0;try{for(var I,j,O=0;;){if(E.t.lastIndex=O,I=E.t.exec(t),!I)break;j=m(t.substring(O,I.index),I[0]),O=I.index+j}for(m(t.substr(O)),w=E;w.parent;w=w.parent)w.cN&&(k+=C);return{r:M,value:k,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function f(e,t){t=t||y.languages||E(x);var r={r:0,value:n(e)},i=r;return t.filter(R).forEach(function(n){var t=l(n,e,!1);t.language=n,t.r>i.r&&(i=t),t.r>r.r&&(i=r,r=t)}),i.language&&(r.second_best=i),r}function g(e){return y.tabReplace||y.useBR?e.replace(M,function(e,n){return y.useBR&&"\n"===e?"
":y.tabReplace?n.replace(/\t/g,y.tabReplace):void 0}):e}function h(e,n,t){var r=n?L[n]:t,i=[e.trim()];return e.match(/\bhljs\b/)||i.push("hljs"),-1===e.indexOf(r)&&i.push(r),i.join(" ").trim()}function p(e){var n,t,r,o,s,p=a(e);i(p)||(y.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=p?l(p,s,!0):f(s),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),s)),r.value=g(r.value),e.innerHTML=r.value,e.className=h(e.className,p,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function d(e){y=o(y,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");w.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function N(){return E(x)}function R(e){return e=(e||"").toLowerCase(),x[e]||x[L[e]]}var w=[],E=Object.keys,x={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",y={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},I={"&":"&","<":"<",">":">"};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=R,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var i=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return i.c.push(e.PWM),i.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),i},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("clojure",function(e){var t={"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},i=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"symbol",b:"[:]{1,2}"+n},f={b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"name",b:n,starts:h},b=[f,i,m,p,c,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,i,m,p,c,u,l,s,d]}});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("elixir",function(e){var r="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",b="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",c={cN:"subst",b:"#\\{",e:"}",l:r,k:b},a={cN:"string",c:[e.BE,c],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},i={cN:"function",bK:"def defp defmacro",e:/\B\b/,c:[e.inherit(e.TM,{b:r,endsParent:!0})]},l=e.inherit(i,{cN:"class",bK:"defimpl defmodule defprotocol defrecord",e:/\bdo\b|$|;/}),s=[a,e.HCM,l,i,{cN:"symbol",b:":(?!\\s)",c:[a,{b:n}],r:0},{cN:"symbol",b:r+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"->"},{b:"("+e.RSR+")\\s*",c:[e.HCM,{cN:"regexp",i:"\\n",c:[e.BE,c],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];return c.c=s,{l:r,k:b,c:s}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("python",function(e){var r={cN:"meta",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},a={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},l={cN:"params",b:/\(/,e:/\)/,c:["self",r,a,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)|=>/,c:[r,a,b,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,l,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("ocaml",function(e){return{aliases:["ml"],k:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)",r:0},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"type",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*",r:0},e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("haskell",function(e){var i={v:[e.C("--","$"),e.C("{-","-}",{c:["self"]})]},a={cN:"meta",b:"{-#",e:"#-}"},l={cN:"meta",b:"^#",e:"$"},c={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n={b:"\\(",e:"\\)",i:'"',c:[a,l,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TM,{b:"[_a-z][\\w']*"}),i]},s={b:"{",e:"}",c:n.c};return{aliases:["hs"],k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{bK:"module",e:"where",k:"module where",c:[n,i],i:"\\W\\.|;"},{b:"\\bimport\\b",e:"$",k:"import qualified as hiding",c:[n,i],i:"\\W\\.|;"},{cN:"class",b:"^(\\s*)?(class|instance)\\b",e:"where",k:"class family instance where",c:[c,n,i]},{cN:"class",b:"\\b(data|(new)?type)\\b",e:"$",k:"data family type newtype deriving",c:[a,c,n,s,i]},{bK:"default",e:"$",c:[c,n,i]},{bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{b:"\\bforeign\\b",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[c,e.QSM,i]},{cN:"meta",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},a,l,e.QSM,e.CNM,c,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),i,{b:"->|<-"}]}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},_={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},i=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:_,l:i,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:i,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var l="[>?]>",o="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+l+"|"+o+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(w).concat(d)}});hljs.registerLanguage("cs",function(e){var i={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double else enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while nameof add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},r={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},t=e.inherit(r,{i:/\n/}),a={cN:"subst",b:"{",e:"}",k:i},n=e.inherit(a,{i:/\n/}),c={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,n]},s={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},a]},o=e.inherit(s,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},n]});a.c=[s,c,r,e.ASM,e.QSM,e.CNM,e.CBCM],n.c=[o,c,t,e.ASM,e.QSM,e.CNM,e.inherit(e.CBCM,{i:/\n/})];var l={v:[s,c,r,e.ASM,e.QSM]},b=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},l,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+b+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[l,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("typescript",function(e){var r={keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void"};return{aliases:["ts"],k:r,c:[{cN:"meta",b:/^\s*['"]use strict['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM],r:0},{cN:"function",b:"function",e:/[\{;]/,eE:!0,k:r,c:["self",e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/%/,r:0},{bK:"constructor",e:/\{/,eE:!0,c:["self",{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}]},{b:/module\./,k:{built_in:"module"},r:0},{bK:"module",e:/\{/,eE:!0},{bK:"interface",e:/\{/,eE:!0,k:"interface extends"},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("elm",function(e){var i={v:[e.C("--","$"),e.C("{-","-}",{c:["self"]})]},t={cN:"type",b:"\\b[A-Z][\\w']*",r:0},c={b:"\\(",e:"\\)",i:'"',c:[{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},i]},n={b:"{",e:"}",c:c.c};return{k:"let in if then else case of where module import exposing type alias as infix infixl infixr port effect command subscription",c:[{bK:"port effect module",e:"exposing",k:"port effect module where command subscription exposing",c:[c,i],i:"\\W\\.|;"},{b:"import",e:"$",k:"import as exposing",c:[c,i],i:"\\W\\.|;"},{b:"type",e:"$",k:"type alias",c:[t,c,n,i]},{bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{b:"port",e:"$",k:"port",c:[i]},e.QSM,e.CNM,t,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),i,{b:"->|<-"}]}});hljs.registerLanguage("fsharp",function(e){var t={b:"<",e:">",c:[e.inherit(e.TM,{b:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],k:"abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",i:/\/\*/,c:[{cN:"keyword",b:/\b(yield|return|let|do)!/},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},e.C("\\(\\*","\\*\\)"),{cN:"class",bK:"type",e:"\\(|=|$",eE:!0,c:[e.UTM,t]},{cN:"meta",b:"\\[<",e:">\\]",r:10},{cN:"symbol",b:"\\B('[A-Za-z])\\b",c:[e.BE]},e.CLCM,e.inherit(e.QSM,{i:null}),e.CNM]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}}); -------------------------------------------------------------------------------- /assets/highlight/monokai-sublime.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Monokai Sublime style. Derived from Monokai by noformnocontent http://nn.mit-license.org/ 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #23241f; 12 | } 13 | 14 | .hljs, 15 | .hljs-tag, 16 | .hljs-subst { 17 | color: #f8f8f2; 18 | } 19 | 20 | .hljs-strong, 21 | .hljs-emphasis { 22 | color: #a8a8a2; 23 | } 24 | 25 | .hljs-bullet, 26 | .hljs-quote, 27 | .hljs-number, 28 | .hljs-regexp, 29 | .hljs-literal, 30 | .hljs-link { 31 | color: #ae81ff; 32 | } 33 | 34 | .hljs-code, 35 | .hljs-title, 36 | .hljs-section, 37 | .hljs-selector-class { 38 | color: #a6e22e; 39 | } 40 | 41 | .hljs-strong { 42 | font-weight: bold; 43 | } 44 | 45 | .hljs-emphasis { 46 | font-style: italic; 47 | } 48 | 49 | .hljs-keyword, 50 | .hljs-selector-tag, 51 | .hljs-name, 52 | .hljs-attr { 53 | color: #f92672; 54 | } 55 | 56 | .hljs-symbol, 57 | .hljs-attribute { 58 | color: #66d9ef; 59 | } 60 | 61 | .hljs-params, 62 | .hljs-class .hljs-title { 63 | color: #f8f8f2; 64 | } 65 | 66 | .hljs-string, 67 | .hljs-type, 68 | .hljs-built_in, 69 | .hljs-builtin-name, 70 | .hljs-selector-id, 71 | .hljs-selector-attr, 72 | .hljs-selector-pseudo, 73 | .hljs-addition, 74 | .hljs-variable, 75 | .hljs-template-variable { 76 | color: #e6db74; 77 | } 78 | 79 | .hljs-comment, 80 | .hljs-deletion, 81 | .hljs-meta { 82 | color: #75715e; 83 | } 84 | -------------------------------------------------------------------------------- /assets/highlight/railscasts.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Railscasts-like style (c) Visoft, Inc. (Damien White) 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #232323; 12 | color: #e6e1dc; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #bc9458; 18 | font-style: italic; 19 | } 20 | 21 | .hljs-keyword, 22 | .hljs-selector-tag { 23 | color: #c26230; 24 | } 25 | 26 | .hljs-string, 27 | .hljs-number, 28 | .hljs-regexp, 29 | .hljs-variable, 30 | .hljs-template-variable { 31 | color: #a5c261; 32 | } 33 | 34 | .hljs-subst { 35 | color: #519f50; 36 | } 37 | 38 | .hljs-tag, 39 | .hljs-name { 40 | color: #e8bf6a; 41 | } 42 | 43 | .hljs-type { 44 | color: #da4939; 45 | } 46 | 47 | 48 | .hljs-symbol, 49 | .hljs-bullet, 50 | .hljs-built_in, 51 | .hljs-builtin-name, 52 | .hljs-attr, 53 | .hljs-link { 54 | color: #6d9cbe; 55 | } 56 | 57 | .hljs-params { 58 | color: #d0d0ff; 59 | } 60 | 61 | .hljs-attribute { 62 | color: #cda869; 63 | } 64 | 65 | .hljs-meta { 66 | color: #9b859d; 67 | } 68 | 69 | .hljs-title, 70 | .hljs-section { 71 | color: #ffc66d; 72 | } 73 | 74 | .hljs-addition { 75 | background-color: #144212; 76 | color: #e6e1dc; 77 | display: inline-block; 78 | width: 100%; 79 | } 80 | 81 | .hljs-deletion { 82 | background-color: #600; 83 | color: #e6e1dc; 84 | display: inline-block; 85 | width: 100%; 86 | } 87 | 88 | .hljs-selector-class { 89 | color: #9b703f; 90 | } 91 | 92 | .hljs-selector-id { 93 | color: #8b98ab; 94 | } 95 | 96 | .hljs-emphasis { 97 | font-style: italic; 98 | } 99 | 100 | .hljs-strong { 101 | font-weight: bold; 102 | } 103 | 104 | .hljs-link { 105 | text-decoration: underline; 106 | } 107 | -------------------------------------------------------------------------------- /assets/highlight/solarized-dark.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #002b36; 12 | color: #839496; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #586e75; 18 | } 19 | 20 | /* Solarized Green */ 21 | .hljs-keyword, 22 | .hljs-selector-tag, 23 | .hljs-addition { 24 | color: #859900; 25 | } 26 | 27 | /* Solarized Cyan */ 28 | .hljs-number, 29 | .hljs-string, 30 | .hljs-meta .hljs-meta-string, 31 | .hljs-literal, 32 | .hljs-doctag, 33 | .hljs-regexp { 34 | color: #2aa198; 35 | } 36 | 37 | /* Solarized Blue */ 38 | .hljs-title, 39 | .hljs-section, 40 | .hljs-name, 41 | .hljs-selector-id, 42 | .hljs-selector-class { 43 | color: #268bd2; 44 | } 45 | 46 | /* Solarized Yellow */ 47 | .hljs-attribute, 48 | .hljs-attr, 49 | .hljs-variable, 50 | .hljs-template-variable, 51 | .hljs-class .hljs-title, 52 | .hljs-type { 53 | color: #b58900; 54 | } 55 | 56 | /* Solarized Orange */ 57 | .hljs-symbol, 58 | .hljs-bullet, 59 | .hljs-subst, 60 | .hljs-meta, 61 | .hljs-meta .hljs-keyword, 62 | .hljs-selector-attr, 63 | .hljs-selector-pseudo, 64 | .hljs-link { 65 | color: #cb4b16; 66 | } 67 | 68 | /* Solarized Red */ 69 | .hljs-built_in, 70 | .hljs-deletion { 71 | color: #dc322f; 72 | } 73 | 74 | .hljs-formula { 75 | background: #073642; 76 | } 77 | 78 | .hljs-emphasis { 79 | font-style: italic; 80 | } 81 | 82 | .hljs-strong { 83 | font-weight: bold; 84 | } 85 | -------------------------------------------------------------------------------- /available-languages.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Purescript", 4 | "languageCode": "haskell" 5 | }, 6 | { 7 | "name": "Haskell", 8 | "languageCode": "haskell" 9 | }, 10 | { 11 | "name": "Elm", 12 | "languageCode": "elm" 13 | }, 14 | { 15 | "name": "F#", 16 | "languageCode": "fsharp" 17 | }, 18 | { 19 | "name": "Empty", 20 | "languageCode": "emptyslot" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /concepts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Forward function application", 4 | "description": "Apply / Pipe", 5 | "index": 0, 6 | "notes": "Applies an argument to a function. The Apply/Pipe-forward operator lets you pass an intermediate result onto the next function. The result of the left argument is passed as an argument to the right function. Data-oriented approach, more idiomatic in F# and Elm.", 7 | "languages": [ 8 | { 9 | "name": "Purescript", 10 | "code": "#, applyFlipped" 11 | }, 12 | { 13 | "name": "Haskell", 14 | "code": "&" 15 | }, 16 | { 17 | "name": "Elm", 18 | "code": "|>", 19 | "example": ["(|>) : a -> (a -> b) -> b", 20 | "", 21 | "employeeBossStreet : Employee -> String", 22 | "employeeBossStreet employee = employee", 23 | " |> boss", 24 | " |> address", 25 | " |> street", 26 | "", 27 | "employeeBossStreet dummyEmployeeRecord", 28 | ">\"DummyEmployeeBossStreetName\" : String." 29 | ] 30 | }, { 31 | "name": "F#", 32 | "code": "|>", 33 | "example": ["( |> ) : 'T1 -> ('T1 -> 'U) -> 'U ", 34 | "", 35 | "let employeeBossStreet (employee: Employee) : string = ", 36 | " employee", 37 | " |> boss", 38 | " |> address", 39 | " |> street", 40 | "", 41 | "employeeBossStreet dummyEmployeeRecord", 42 | ">val it : string = \"DummyEmployeeBossStreetName\"" 43 | ] 44 | } 45 | ], 46 | "links": [ 47 | { 48 | "url": "https://pursuit.purescript.org/packages/purescript-prelude/2.1.0/docs/Prelude#v:(#)", 49 | "description": "Purescript # reference" 50 | }, 51 | { 52 | "url": "http://stackoverflow.com/questions/1457140/haskell-composition-vs-fs-pipe-forward-operator", 53 | "description": "Stack Overflow discussion" 54 | }, 55 | { 56 | "url": "http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#|>", 57 | "description": "Elm Basics - (|>)" 58 | }, 59 | { 60 | "url": "https://www.reddit.com/r/haskell/comments/3mttyh/elms_operator/", 61 | "description": "A discussion on idiomatic operators in Elm and Haskell" 62 | } 63 | ] 64 | }, 65 | { 66 | "name": "Backward function application", 67 | "description": "Apply / Pipe", 68 | "index": 1, 69 | "notes": "Applies a function to an argument. Can be used to avoid parentheses and improve readability. The result of the right argument is applied to the left argument.", 70 | "languages": [ 71 | { 72 | "name": "Purescript", 73 | "code": "$, apply", 74 | "example": ["apply :: forall a b. (a -> b) -> a -> b", 75 | "apply f x = f x", 76 | "", 77 | "--without operator", 78 | "employeeBossStreet :: Employee -> String", 79 | "employeeBossStreet employee =", 80 | " street (address (boss employee))", 81 | "employeeBossStreet dummyEmployeeRecord", 82 | ">\"DummyEmployeeBossStreetName\"", 83 | "", 84 | "--with operator", 85 | "employeeBossStreet :: Employee -> String", 86 | "employeeBossStreet employee =", 87 | " street $ address $ boss employee", 88 | "employeeBossStreet dummyEmployeeRecord", 89 | ">\"DummyEmployeeBossStreetName\"" 90 | ] 91 | }, 92 | { 93 | "name": "Haskell", 94 | "code": "$", 95 | "example": ["($) :: (a -> b) -> a -> b", 96 | "F x = f x", 97 | "", 98 | "= street (address (boss employee))", 99 | "= street $ address $ boss employee" 100 | ] 101 | }, 102 | { 103 | "name": "Elm", 104 | "code": "<|", 105 | "example": ["(<|) : (a -> b) -> a -> b", 106 | "", 107 | "--without operator", 108 | "employeeBossStreet : Employee -> String", 109 | "employeeBossStreet employee = ", 110 | " street (address (boss employee))", 111 | "", 112 | "employeeBossStreet dummyEmployeeRecord", 113 | ">\"DummyEmployeeBossStreetName\" : String. ", 114 | "", 115 | "-- with operator", 116 | "employeeBossStreet : Employee -> String", 117 | "employeeBossStreet employee = ", 118 | " street <| address <| boss employee", 119 | "", 120 | "employeeBossStreet dummyEmployeeRecord", 121 | ">\"DummyEmployeeBossStreetName\" : String." 122 | ] 123 | }, { 124 | "name": "F#", 125 | "code": "<|", 126 | "example": [ "( <| ) : ('T -> 'U) -> 'T -> 'U", 127 | "", 128 | "//without operator", 129 | "let employeeBossStreet (employee: Employee) : string =", 130 | " street (address (boss employee))", 131 | "", 132 | "employeeBossStreet dummyEmployeeRecord", 133 | ">val it : string = \"DummyEmployeeBossStreetName\" ", 134 | "", 135 | "//with operator", 136 | "let employeeBossStreet (employee: Employee) : string =", 137 | " street <| address <| boss employee", 138 | "", 139 | "employeeBossStreet dummyEmployeeRecord", 140 | ">val it : string = \"DummyEmployeeBossStreetName\"" 141 | ] 142 | } 143 | ], 144 | "links": [ 145 | { 146 | "url": "https://pursuit.purescript.org/packages/purescript-prelude/2.1.0/docs/Prelude#v:($)", 147 | "description": "Purescript $ reference" 148 | }, 149 | { 150 | "url": "http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#<|", 151 | "description": "Elm Basics - (<|)" 152 | }, 153 | { 154 | "url": "https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/functions/index", 155 | "description": "F# functions reference" 156 | }, 157 | { 158 | "url": "https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/symbol-and-operator-reference/", 159 | "description": "F# operator reference" 160 | } 161 | ] 162 | }, 163 | { 164 | "name": "Composition - forward", 165 | "description": "Forward/right", 166 | "notes": "Creating a new, combined function by piping the result of the left argument to the right argument. A function-oriented approach, combining functions first, actual values input later.", 167 | "index": 2, 168 | "languages": [ 169 | { 170 | "name": "Purescript", 171 | "code": ">>>, composeFlipped", 172 | "example": ["composeFlipped :: forall a b c d. Semigroupoid a => a b c -> a c d -> a b d", 173 | "", 174 | "employeeBossStreet :: (Employee -> String)", 175 | "employeeBossStreet =", 176 | " boss >>> address >>> street", 177 | "", 178 | "employeeBossStreet dummyEmployeeRecord", 179 | ">\"DummyEmployeeBossStreetName\"" 180 | ] 181 | 182 | }, 183 | { 184 | "name": "Haskell", 185 | "code": ">>>", 186 | "example": ["employeeBossStreet = (boss >>> address >>> street) employee" 187 | ] 188 | }, 189 | { 190 | "name": "Elm", 191 | "code": ">>", 192 | "example": ["(>>) : (a -> b) -> (b -> c) -> a -> c", 193 | "", 194 | "employeeBossStreet : (Employee -> String)", 195 | "employeeBossStreet =", 196 | " boss >> address >> street", 197 | "", 198 | "employeeBossStreet dummyEmployeeRecord", 199 | ">\"DummyEmployeeBossStreetName\" : String." 200 | ] 201 | }, 202 | { 203 | "name": "F#", 204 | "code": ">>", 205 | "example": ["(>>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c", 206 | "", 207 | "let employeeBossStreet : (Employee -> string) =", 208 | " boss >> address >> street", 209 | "", 210 | "employeeBossStreet dummyEmployeeRecord", 211 | ">val it : string = \"DummyEmployeeBossStreetName\"" 212 | ] 213 | } 214 | ], 215 | "links": [ 216 | { 217 | "url": "https://wiki.haskell.org/Function_composition", 218 | "description": "Haskell wiki" 219 | }, 220 | { 221 | "url": "https://fsharpforfunandprofit.com/posts/function-composition/", 222 | "description": "F# for fun and profilt - function composition" 223 | }, 224 | { 225 | "url": "http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#>>", 226 | "description": "Elm - basics >>" 227 | } 228 | ] 229 | }, 230 | { 231 | "name": "Composition - backward", 232 | "description": "Backward/left", 233 | "notes": "Creating a new, combined function by piping the result of the right argument to the left argument. A function-oriented approach, combining functions first, actual values input later. More idiomatic in Purescript/Haskell. The Control.Arrow module in Haskell base has (<<<) in addition to (>>>). For function arrows, (<<<) specializes to (.).", 234 | "index": 3, 235 | "languages": [ 236 | { 237 | "name": "Purescript", 238 | "code": "<<<, compose", 239 | "example": ["compose :: forall a b c. (b -> c) -> (a -> b) -> a -> c", 240 | "", 241 | "employeeBossStreet :: (Employee -> String)", 242 | "employeeBossStreet =", 243 | " street <<< address <<< boss", 244 | "", 245 | "employeeBossStreet dummyEmployeeRecord", 246 | ">\"DummyEmployeeBossStreetName\"" 247 | ] 248 | }, 249 | { 250 | "name": "Haskell", 251 | "code": "<<<, .", 252 | "example": ["employeeBossStreet = (street . address . boss) employee", 253 | "", 254 | "employeeBossStreet = (street <<< address <<< boss) employee" 255 | ] 256 | }, 257 | { 258 | "name": "Elm", 259 | "code": "<<", 260 | "example": ["(<<) : (b -> c) -> (a -> b) -> a -> c", 261 | "", 262 | "employeeBossStreet : (Employee -> String)", 263 | "employeeBossStreet =", 264 | " street << address << boss", 265 | "", 266 | "employeeBossStreet dummyEmployeeRecord", 267 | ">\"DummyEmployeeBossStreetName\" : String." 268 | ] 269 | }, 270 | { 271 | "name": "F#", 272 | "code": "<<", 273 | "example": ["(<<) : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c", 274 | "", 275 | "let employeeBossStreet : (Employee -> string) =", 276 | " street << address << boss", 277 | "", 278 | "employeeBossStreet dummyEmployeeRecord", 279 | ">val it : string = \"DummyEmployeeBossStreetName\"" 280 | ] 281 | } 282 | ], 283 | "links": [ 284 | { 285 | "url": "https://wiki.haskell.org/Function_composition", 286 | "description": "Haskell wiki" 287 | }, 288 | { 289 | "url": "https://fsharpforfunandprofit.com/posts/function-composition/", 290 | "description": "F# for fun and profilt - function composition" 291 | }, 292 | { 293 | "url": "http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#<<", 294 | "description": "Elm - basics (<<)" 295 | } 296 | ] 297 | }, 298 | { 299 | "name": "Unit type", 300 | "description": "Empty", 301 | "index": 3, 302 | "languages": [ 303 | { 304 | "name": "Purescript", 305 | "code": "Unit" 306 | }, 307 | { 308 | "name": "Haskell", 309 | "code": "()" 310 | }, 311 | { 312 | "name": "Elm", 313 | "code": "()" 314 | }, { 315 | "name": "F#", 316 | "code": "()" 317 | } 318 | ] 319 | }, 320 | { 321 | "name": "Anonymous function", 322 | "description": "Lambda", 323 | "index": 3, 324 | "languages": [ 325 | { 326 | "name": "Purescript", 327 | "code": "\\x -> x + 1" 328 | }, 329 | { 330 | "name": "Haskell", 331 | "code": "\\x -> x + 1" 332 | }, 333 | { 334 | "name": "Elm", 335 | "code": "\\x -> x + 1" 336 | }, { 337 | "name": "F#", 338 | "code": "fun x -> x + 1" 339 | } 340 | ] 341 | }, 342 | { 343 | "name": "Identity function", 344 | "description": "", 345 | "index": 3, 346 | "languages": [ 347 | { 348 | "name": "Purescript", 349 | "code": "identity" 350 | }, 351 | { 352 | "name": "Haskell", 353 | "code": "id" 354 | }, 355 | { 356 | "name": "Elm", 357 | "code": "identity" 358 | }, { 359 | "name": "F#", 360 | "code": "id" 361 | } 362 | ] 363 | }, 364 | { 365 | "name": "Tuple", 366 | "description": "Definition", 367 | "index": 3, 368 | "languages": [ 369 | { 370 | "name": "Purescript", 371 | "code": "Tuple a b" 372 | }, 373 | { 374 | "name": "Haskell", 375 | "code": "(Int, String)" 376 | }, 377 | { 378 | "name": "Elm", 379 | "code": "(Int, String)" 380 | }, { 381 | "name": "F#", 382 | "code": "int * string" 383 | } 384 | ] 385 | }, 386 | { "name": "Tuple", 387 | "description": "Usage", 388 | "index": 3, 389 | "languages": [ 390 | { 391 | "name": "Purescript", 392 | "code": "Tuple 2 \"Test\"" 393 | }, 394 | { 395 | "name": "Haskell", 396 | "code": "(2, \"Test\")" 397 | }, 398 | { 399 | "name": "Elm", 400 | "code": "(2, \"Test\")" 401 | }, { 402 | "name": "F#", 403 | "code": "(2, \"Test\")" 404 | } 405 | ] 406 | }, 407 | { 408 | "name": "Record types", 409 | "description": "", 410 | "index": 3, 411 | "languages": [ 412 | { 413 | "name": "Purescript", 414 | "code": "type Point = { x :: Int, y :: Int}" 415 | }, 416 | { 417 | "name": "Haskell", 418 | "code": "data Point = Point { x :: Int, y :: Int}" 419 | }, 420 | { 421 | "name": "Elm", 422 | "code": "type alias Point = { x : Int, y : Int}" 423 | }, { 424 | "name": "F#", 425 | "code": "type Point = {\r x : int; y : int}" 426 | } 427 | ] 428 | }, 429 | { 430 | "name": "Union types", 431 | "description": "Sum types / Discriminated unions / Algebraic data types (ADT)", 432 | "index": 3, 433 | "languages": [ 434 | { 435 | "name": "Purescript", 436 | "code": "data Shape = Circle Point Int | Line Point Point" 437 | }, 438 | { 439 | "name": "Haskell", 440 | "code": "data Shape = Circle Point Int | Line Point Point" 441 | }, 442 | { 443 | "name": "Elm", 444 | "code": "type Shape = Circle Point Int | Line Point Point" 445 | }, { 446 | "name": "F#", 447 | "code": "type Shape = Circle of Point * int | Line of Point * Point" 448 | } 449 | ] 450 | }, 451 | { 452 | "name": "Maybe/Option", 453 | "description": "", 454 | "index": 3, 455 | "languages": [ 456 | { 457 | "name": "Purescript", 458 | "code": "data Maybe a = Just a | Nothing" 459 | }, 460 | { 461 | "name": "Haskell", 462 | "code": "data Maybe a = Just a | Nothing" 463 | }, 464 | { 465 | "name": "Elm", 466 | "code": "type Maybe a = Just a | Nothing" 467 | }, { 468 | "name": "F#", 469 | "code": "type Option<'a> = | Some of 'a | None" 470 | } 471 | ] 472 | }, 473 | { 474 | "name": "Either / Result", 475 | "description": "", 476 | "index": 3, 477 | "languages": [ 478 | { 479 | "name": "Purescript", 480 | "code": "data Either a b = Left a | Right b" 481 | }, 482 | { 483 | "name": "Haskell", 484 | "code": "data Either a b = Left a | Right b" 485 | }, 486 | { 487 | "name": "Elm", 488 | "code": "type Result error value = Ok value | Err error" 489 | }, { 490 | "name": "F#", 491 | "code": "(in F# 4.1) type Result<'T,'TError> = | Ok of 'T | Error of 'TError" 492 | } 493 | ] 494 | }, 495 | { 496 | "name": "Functor map", 497 | "description": "Map", 498 | "index": 3, 499 | "languages": [ 500 | { 501 | "name": "Purescript", 502 | "code": "<$>, map" 503 | }, 504 | { 505 | "name": "Haskell", 506 | "code": "<$>, fmap" 507 | }, 508 | { 509 | "name": "Elm", 510 | "code": "map" 511 | }, { 512 | "name": "F#", 513 | "code": "map" 514 | } 515 | ] 516 | }, 517 | { 518 | "name": "Functor apply", 519 | "description": "Apply", 520 | "notes" : "*andMap is not core in Elm, but is often used in Packages.", 521 | "index": 3, 522 | "languages": [ 523 | { 524 | "name": "Purescript", 525 | "code": "<*>, apply" 526 | }, 527 | { 528 | "name": "Haskell", 529 | "code": "<*>" 530 | }, 531 | { 532 | "name": "Elm", 533 | "code": "andMap(*notes)" 534 | }, { 535 | "name": "F#", 536 | "code": "apply" 537 | } 538 | ], 539 | "links": [ 540 | { 541 | "url": "http://klaftertief.github.io/elm-search/?q=andMap", 542 | "description": "Elm - External packages using andMap" 543 | } 544 | ] 545 | }, 546 | { 547 | "name": "Functor lift", 548 | "description": "", 549 | "index": 3, 550 | "languages": [ 551 | { 552 | "name": "Purescript", 553 | "code": "liftN" 554 | }, 555 | { 556 | "name": "Haskell", 557 | "code": "liftN" 558 | }, 559 | { 560 | "name": "Elm", 561 | "code": "mapN" 562 | }, { 563 | "name": "F#", 564 | "code": "mapN" 565 | } 566 | ] 567 | }, 568 | { 569 | "name": "Bind", 570 | "description": "", 571 | "index": 3, 572 | "languages": [ 573 | { 574 | "name": "Purescript", 575 | "code": ">>=, bind" 576 | }, 577 | { 578 | "name": "Haskell", 579 | "code": ">>=" 580 | }, 581 | { 582 | "name": "Elm", 583 | "code": "andThen" 584 | }, { 585 | "name": "F#", 586 | "code": "bind" 587 | } 588 | ] 589 | }, 590 | { 591 | "name": "Comments", 592 | "description": "", 593 | "index": 3, 594 | "notes": "Single line comments, block comments and documentation comments.", 595 | "languages": [ 596 | { 597 | "name": "Purescript", 598 | "code": "-- Line {- Block -} --| Documentation", 599 | "example": ["-- A single line comment", 600 | "{-", 601 | " Comment", 602 | " continued comment {- Nested block -}", 603 | "-}", 604 | "-- | Comments that start with a pipe character, |, are considered documentation, and will appear in the output of tools like psc-docs and Pursuit.", 605 | "-- | Adds two numbers", 606 | "-- This comment does not start with a pipe and will not be part of the documentation", 607 | "add :: Int -> Int -> Int", 608 | "add x y = x + y" 609 | ] 610 | }, 611 | { 612 | "name": "Haskell", 613 | "code": "-- Line {- Block -} --| Documentation", 614 | "example": ["-- A single line comment", 615 | "{-", 616 | " Comment", 617 | " continued comment {- Nested block -}", 618 | "-}", 619 | "-- | Comments that start with a pipe character, |, are considered documentation, and will appear in the output of documentation tools.", 620 | "-- | Adds two numbers", 621 | "add :: Int -> Int -> Int", 622 | "add x y = x + y" 623 | ] 624 | }, 625 | { 626 | "name": "Elm", 627 | "code": "-- Line {- Block -}", 628 | "example": ["-- A single line comment", 629 | "{-", 630 | " Comment", 631 | " continued comment {- Nested block -}", 632 | "-}", 633 | "{- Block comments that start with a pipe character, |, are ", 634 | "considered documentation, and will", 635 | "appear in the output package documentation.", 636 | "", 637 | "@docs add", 638 | "To output documentation, @docs keyword precedes a comma-separated list of values", 639 | "The @docs add, will document the comment preceeding the add function.", 640 | "-}", 641 | "{-|", 642 | "Adds two numbers", 643 | "-}", 644 | "add : Int -> Int -> Int", 645 | "add x y = x + y" 646 | ] 647 | }, { 648 | "name": "F#", 649 | "code": "// Line (* Block *)", 650 | "example": ["// A single line comment", 651 | "(*", 652 | " Comment", 653 | " continued comment", 654 | "*)", 655 | "// XML documentation comments come after ///", 656 | "/// Adds two numbers", 657 | "let add (x:int) (y:int) = x + y" 658 | ] 659 | } 660 | ], 661 | "links": [ 662 | { 663 | "url": "https://github.com/purescript/documentation/blob/master/language/Syntax.md#comments", 664 | "description": "Purescript comments" 665 | }, 666 | { 667 | "url": "http://elm-lang.org/docs/syntax#comments", 668 | "description": "Elm comments" 669 | }, 670 | { 671 | "url": "http://package.elm-lang.org/help/documentation-format", 672 | "description": "Elm package documentation" 673 | }, 674 | { 675 | "url": "https://dungpa.github.io/fsharp-cheatsheet/", 676 | "description": "F# Cheatsheet" 677 | }, 678 | { 679 | "url": "https://wiki.haskell.org/Reference_card#Comments", 680 | "description": "Haskell reference card" 681 | } 682 | ] 683 | }, 684 | { 685 | "name": "Type annotation", 686 | "description": "Function definition", 687 | "index": 3, 688 | "notes": "Annotating types can in many situations be omitted due to type inference, but can improve readability.", 689 | "languages": [ 690 | { 691 | "name": "Purescript", 692 | "code": "add :: Int -> Int -> Int", 693 | "example": ["add :: Int -> Int -> Int", 694 | "add x y = x + y", 695 | "", 696 | "-- Using universally quantified types (generic)", 697 | "flip :: forall a b c. (a -> b -> c) -> b -> a -> c", 698 | "flip f b a = f a b" 699 | ] 700 | }, 701 | { 702 | "name": "Haskell", 703 | "code": "add :: Int -> Int -> Int", 704 | "example": ["add :: Int -> Int -> Int", 705 | "add x y = x + y", 706 | "", 707 | "-- Using generic types (any type)", 708 | "flip :: (a -> b -> c) -> b -> a -> c", 709 | "flip f b a = f a b" 710 | ] 711 | }, 712 | { 713 | "name": "Elm", 714 | "code": "add : Int -> Int -> Int", 715 | "example": ["add : Int -> Int -> Int", 716 | "add x y = x + y", 717 | "", 718 | "-- Using generic types (any type)", 719 | "flip : (a -> b -> c) -> b -> a -> c", 720 | "flip f b a = f a b" 721 | ] 722 | }, { 723 | "name": "F#", 724 | "code": "let add (x:int) (y:int) : int = x + y", 725 | "example": ["let add (x:int) (y:int) : int = x + y" 726 | ] 727 | } 728 | ], 729 | "links": [ 730 | { 731 | "url": "http://elm-lang.org/docs/syntax#type-annotations", 732 | "description": "Elm type annnotations" 733 | }, 734 | { 735 | "url": "https://fsharpforfunandprofit.com/posts/function-signatures/", 736 | "description": "F# for fun and profit function signatures" 737 | }, 738 | { 739 | "url": "http://learnyouahaskell.com/types-and-typeclasses", 740 | "description": "Haskell types and typeclasses" 741 | } 742 | ] 743 | }, 744 | { 745 | "name": "Generic types", 746 | "description": "Type variables", 747 | "index": 3, 748 | "notes": "Generic functions and types enable you to write code that works with a variety of types without repeating the code for each type. Type variables/generic types can have names longer than one character, but usually given one character names.", 749 | "languages": [ 750 | { 751 | "name": "Purescript", 752 | "code": "forall a b.", 753 | "example": ["-- Any lowercase identifier can be used, like a, msg.", 754 | "flip :: forall a b c. (a -> b -> c) -> b -> a -> c" 755 | ] 756 | }, 757 | { 758 | "name": "Haskell", 759 | "code": "a b", 760 | "example": ["-- Any lowercase identifier can be used, like a, msg.", 761 | "flip :: (a -> b -> c) -> b -> a -> c" 762 | ] 763 | }, 764 | { 765 | "name": "Elm", 766 | "code": "a b", 767 | "example": ["-- Any lowercase identifier can be used, like a, msg.", 768 | "flip : (a -> b -> c) -> b -> a -> c" 769 | ] 770 | }, { 771 | "name": "F#", 772 | "code": "'a 'b 'C", 773 | "example": ["// Generics are identified by ' and can use upper/lowercase, like 'a, 'Msg.", 774 | "val flip = ('a -> 'b -> 'c) -> 'b -> 'a -> 'c", 775 | "// Can also use x y =", 777 | " printfn \"%A, %A\" x y" 778 | ] 779 | } 780 | ], 781 | "links": [ 782 | { 783 | "url": "https://www.tutorialspoint.com/fsharp/fsharp_generics.htm", 784 | "description": "F# Generics" 785 | }, 786 | { 787 | "url": "https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/generics/", 788 | "description": "F# Generics - Microsoft F# language reference" 789 | }, 790 | { 791 | "url": "https://www.elm-tutorial.org/en/01-foundations/03-functions-2.html", 792 | "description": "Elm tutorial - functions" 793 | } 794 | ] 795 | } 796 | ] 797 | -------------------------------------------------------------------------------- /demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakonrossebo/functional-programming-babelfish/e54a5eebcc731074fa47e4e6aa932378e5a7c5dd/demo.png -------------------------------------------------------------------------------- /docs/assets/analytics.js: -------------------------------------------------------------------------------- 1 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 2 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 3 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 4 | })(window,document,'script','https://www.google-analytics.com/analytics.js','ga'); 5 | 6 | ga('create', 'UA-92960408-1', 'auto'); 7 | ga('send', 'pageview'); 8 | -------------------------------------------------------------------------------- /docs/assets/highlight/highlight.pack.js: -------------------------------------------------------------------------------- 1 | /*! highlight.js v9.9.0 | BSD3 License | git.io/hljslicense */ 2 | !function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/[&<>]/gm,function(e){return I[e]})}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function i(e){return k.test(e)}function a(e){var n,t,r,a,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return R(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(a=o[n],i(a)||R(a))return a}function o(e,n){var t,r={};for(t in e)r[t]=e[t];if(n)for(t in n)r[t]=n[t];return r}function u(e){var n=[];return function r(e,i){for(var a=e.firstChild;a;a=a.nextSibling)3===a.nodeType?i+=a.nodeValue.length:1===a.nodeType&&(n.push({event:"start",offset:i,node:a}),i=r(a,i),t(a).match(/br|hr|img|input/)||n.push({event:"stop",offset:i,node:a}));return i}(e,0),n}function c(e,r,i){function a(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){l+=""}function c(e){("start"===e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=a();if(l+=n(i.substring(s,g[0].offset)),s=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=a();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(i.substr(s))}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(i,a){if(!i.compiled){if(i.compiled=!0,i.k=i.k||i.bK,i.k){var u={},c=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");u[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof i.k?c("keyword",i.k):E(i.k).forEach(function(e){c(e,i.k[e])}),i.k=u}i.lR=t(i.l||/\w+/,!0),a&&(i.bK&&(i.b="\\b("+i.bK.split(" ").join("|")+")\\b"),i.b||(i.b=/\B|\b/),i.bR=t(i.b),i.e||i.eW||(i.e=/\B|\b/),i.e&&(i.eR=t(i.e)),i.tE=n(i.e)||"",i.eW&&a.tE&&(i.tE+=(i.e?"|":"")+a.tE)),i.i&&(i.iR=t(i.i)),null==i.r&&(i.r=1),i.c||(i.c=[]);var s=[];i.c.forEach(function(e){e.v?e.v.forEach(function(n){s.push(o(e,n))}):s.push("self"===e?i:e)}),i.c=s,i.c.forEach(function(e){r(e,i)}),i.starts&&r(i.starts,a);var l=i.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([i.tE,i.i]).map(n).filter(Boolean);i.t=l.length?t(l.join("|"),!0):{exec:function(){return null}}}}r(e)}function l(e,t,i,a){function o(e,n){var t,i;for(t=0,i=n.c.length;i>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!i&&r(n.iR,e)}function g(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function h(e,n,t,r){var i=r?"":y.classPrefix,a='',a+n+o}function p(){var e,t,r,i;if(!E.k)return n(B);for(i="",t=0,E.lR.lastIndex=0,r=E.lR.exec(B);r;)i+=n(B.substring(t,r.index)),e=g(E,r),e?(M+=e[1],i+=h(e[0],n(r[0]))):i+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(B);return i+n(B.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!x[E.sL])return n(B);var t=e?l(E.sL,B,!0,L[E.sL]):f(B,E.sL.length?E.sL:void 0);return E.r>0&&(M+=t.r),e&&(L[E.sL]=t.top),h(t.language,t.value,!1,!0)}function b(){k+=null!=E.sL?d():p(),B=""}function v(e){k+=e.cN?h(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(B+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?B+=n:(t.eB&&(B+=n),b(),t.rB||t.eB||(B=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var i=E;i.skip?B+=n:(i.rE||i.eE||(B+=n),b(),i.eE&&(B=n));do E.cN&&(k+=C),E.skip||(M+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),i.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return B+=n,n.length||1}var N=R(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var w,E=a||N,L={},k="";for(w=E;w!==N;w=w.parent)w.cN&&(k=h(w.cN,"",!0)+k);var B="",M=0;try{for(var I,j,O=0;;){if(E.t.lastIndex=O,I=E.t.exec(t),!I)break;j=m(t.substring(O,I.index),I[0]),O=I.index+j}for(m(t.substr(O)),w=E;w.parent;w=w.parent)w.cN&&(k+=C);return{r:M,value:k,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function f(e,t){t=t||y.languages||E(x);var r={r:0,value:n(e)},i=r;return t.filter(R).forEach(function(n){var t=l(n,e,!1);t.language=n,t.r>i.r&&(i=t),t.r>r.r&&(i=r,r=t)}),i.language&&(r.second_best=i),r}function g(e){return y.tabReplace||y.useBR?e.replace(M,function(e,n){return y.useBR&&"\n"===e?"
":y.tabReplace?n.replace(/\t/g,y.tabReplace):void 0}):e}function h(e,n,t){var r=n?L[n]:t,i=[e.trim()];return e.match(/\bhljs\b/)||i.push("hljs"),-1===e.indexOf(r)&&i.push(r),i.join(" ").trim()}function p(e){var n,t,r,o,s,p=a(e);i(p)||(y.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n")):n=e,s=n.textContent,r=p?l(p,s,!0):f(s),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),s)),r.value=g(r.value),e.innerHTML=r.value,e.className=h(e.className,p,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function d(e){y=o(y,e)}function b(){if(!b.called){b.called=!0;var e=document.querySelectorAll("pre code");w.forEach.call(e,p)}}function v(){addEventListener("DOMContentLoaded",b,!1),addEventListener("load",b,!1)}function m(n,t){var r=x[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function N(){return E(x)}function R(e){return e=(e||"").toLowerCase(),x[e]||x[L[e]]}var w=[],E=Object.keys,x={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="
",y={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},I={"&":"&","<":"<",">":">"};return e.highlight=l,e.highlightAuto=f,e.fixMarkup=g,e.highlightBlock=p,e.configure=d,e.initHighlighting=b,e.initHighlightingOnLoad=v,e.registerLanguage=m,e.listLanguages=N,e.getLanguage=R,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var i=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return i.c.push(e.PWM),i.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),i},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("clojure",function(e){var t={"builtin-name":"def defonce cond apply if-not if-let if not not= = < > <= >= == + / * - rem quot neg? pos? delay? symbol? keyword? true? false? integer? empty? coll? list? set? ifn? fn? associative? sequential? sorted? counted? reversible? number? decimal? class? distinct? isa? float? rational? reduced? ratio? odd? even? char? seq? vector? string? map? nil? contains? zero? instance? not-every? not-any? libspec? -> ->> .. . inc compare do dotimes mapcat take remove take-while drop letfn drop-last take-last drop-while while intern condp case reduced cycle split-at split-with repeat replicate iterate range merge zipmap declare line-seq sort comparator sort-by dorun doall nthnext nthrest partition eval doseq await await-for let agent atom send send-off release-pending-sends add-watch mapv filterv remove-watch agent-error restart-agent set-error-handler error-handler set-error-mode! error-mode shutdown-agents quote var fn loop recur throw try monitor-enter monitor-exit defmacro defn defn- macroexpand macroexpand-1 for dosync and or when when-not when-let comp juxt partial sequence memoize constantly complement identity assert peek pop doto proxy defstruct first rest cons defprotocol cast coll deftype defrecord last butlast sigs reify second ffirst fnext nfirst nnext defmulti defmethod meta with-meta ns in-ns create-ns import refer keys select-keys vals key val rseq name namespace promise into transient persistent! conj! assoc! dissoc! pop! disj! use class type num float double short byte boolean bigint biginteger bigdec print-method print-dup throw-if printf format load compile get-in update-in pr pr-on newline flush read slurp read-line subvec with-open memfn time re-find re-groups rand-int rand mod locking assert-valid-fdecl alias resolve ref deref refset swap! reset! set-validator! compare-and-set! alter-meta! reset-meta! commute get-validator alter ref-set ref-history-count ref-min-history ref-max-history ensure sync io! new next conj set! to-array future future-call into-array aset gen-class reduce map filter find empty hash-map hash-set sorted-map sorted-map-by sorted-set sorted-set-by vec vector seq flatten reverse assoc dissoc list disj get union difference intersection extend extend-type extend-protocol int nth delay count concat chunk chunk-buffer chunk-append chunk-first chunk-rest max min dec unchecked-inc-int unchecked-inc unchecked-dec-inc unchecked-dec unchecked-negate unchecked-add-int unchecked-add unchecked-subtract-int unchecked-subtract chunk-next chunk-cons chunked-seq? prn vary-meta lazy-seq spread list* str find-keyword keyword symbol gensym force rationalize"},r="a-zA-Z_\\-!.?+*=<>&#'",n="["+r+"]["+r+"0-9/;:]*",a="[-+]?\\d+(\\.\\d+)?",o={b:n,r:0},s={cN:"number",b:a,r:0},i=e.inherit(e.QSM,{i:null}),c=e.C(";","$",{r:0}),d={cN:"literal",b:/\b(true|false|nil)\b/},l={b:"[\\[\\{]",e:"[\\]\\}]"},m={cN:"comment",b:"\\^"+n},p=e.C("\\^\\{","\\}"),u={cN:"symbol",b:"[:]{1,2}"+n},f={b:"\\(",e:"\\)"},h={eW:!0,r:0},y={k:t,l:n,cN:"name",b:n,starts:h},b=[f,i,m,p,c,u,l,s,d,o];return f.c=[e.C("comment",""),y,h],h.c=b,l.c=b,{aliases:["clj"],i:/\S/,c:[f,i,m,p,c,u,l,s,d]}});hljs.registerLanguage("java",function(e){var a="[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",t=a+"(<"+a+"(\\s*,\\s*"+a+")*>)?",r="false synchronized int abstract float private char boolean static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",s="\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",c={cN:"number",b:s,r:0};return{aliases:["jsp"],k:r,i:/<\/|#/,c:[e.C("/\\*\\*","\\*/",{r:0,c:[{b:/\w+@/,r:0},{cN:"doctag",b:"@[A-Za-z]+"}]}),e.CLCM,e.CBCM,e.ASM,e.QSM,{cN:"class",bK:"class interface",e:/[{;=]/,eE:!0,k:"class interface",i:/[:"\[\]]/,c:[{bK:"extends implements"},e.UTM]},{bK:"new throw return else",r:0},{cN:"function",b:"("+t+"\\s+)+"+e.UIR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:r,c:[{b:e.UIR+"\\s*\\(",rB:!0,r:0,c:[e.UTM]},{cN:"params",b:/\(/,e:/\)/,k:r,r:0,c:[e.ASM,e.QSM,e.CNM,e.CBCM]},e.CLCM,e.CBCM]},c,{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"|$)",e:">",k:{name:"style"},c:[t],starts:{e:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"|$)",e:">",k:{name:"script"},c:[t],starts:{e:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("elixir",function(e){var r="[a-zA-Z_][a-zA-Z0-9_]*(\\!|\\?)?",n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",b="and false then defined module in return redo retry end for true self when next until do begin unless nil break not case cond alias while ensure or include use alias fn quote",c={cN:"subst",b:"#\\{",e:"}",l:r,k:b},a={cN:"string",c:[e.BE,c],v:[{b:/'/,e:/'/},{b:/"/,e:/"/}]},i={cN:"function",bK:"def defp defmacro",e:/\B\b/,c:[e.inherit(e.TM,{b:r,endsParent:!0})]},l=e.inherit(i,{cN:"class",bK:"defimpl defmodule defprotocol defrecord",e:/\bdo\b|$|;/}),s=[a,e.HCM,l,i,{cN:"symbol",b:":(?!\\s)",c:[a,{b:n}],r:0},{cN:"symbol",b:r+":",r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{cN:"variable",b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{b:"->"},{b:"("+e.RSR+")\\s*",c:[e.HCM,{cN:"regexp",i:"\\n",c:[e.BE,c],v:[{b:"/",e:"/[a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}],r:0}];return c.c=s,{l:r,k:b,c:s}});hljs.registerLanguage("apache",function(e){var r={cN:"number",b:"[\\$%]\\d+"};return{aliases:["apacheconf"],cI:!0,c:[e.HCM,{cN:"section",b:""},{cN:"attribute",b:/\w+/,r:0,k:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{e:/$/,r:0,k:{literal:"on off all"},c:[{cN:"meta",b:"\\s\\[",e:"\\]$"},{cN:"variable",b:"[\\$%]\\{",e:"\\}",c:["self",r]},r,e.QSM]}}],i:/\S/}});hljs.registerLanguage("python",function(e){var r={cN:"meta",b:/^(>>>|\.\.\.) /},b={cN:"string",c:[e.BE],v:[{b:/(u|b)?r?'''/,e:/'''/,c:[r],r:10},{b:/(u|b)?r?"""/,e:/"""/,c:[r],r:10},{b:/(u|r|ur)'/,e:/'/,r:10},{b:/(u|r|ur)"/,e:/"/,r:10},{b:/(b|br)'/,e:/'/},{b:/(b|br)"/,e:/"/},e.ASM,e.QSM]},a={cN:"number",r:0,v:[{b:e.BNR+"[lLjJ]?"},{b:"\\b(0o[0-7]+)[lLjJ]?"},{b:e.CNR+"[lLjJ]?"}]},l={cN:"params",b:/\(/,e:/\)/,c:["self",r,a,b]};return{aliases:["py","gyp"],k:{keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10 None True False",built_in:"Ellipsis NotImplemented"},i:/(<\/|->|\?)|=>/,c:[r,a,b,e.HCM,{v:[{cN:"function",bK:"def"},{cN:"class",bK:"class"}],e:/:/,i:/[${=;\n,]/,c:[e.UTM,l,{b:/->/,eW:!0,k:"None"}]},{cN:"meta",b:/^[\t ]*@/,e:/$/},{b:/\b(print|exec)\(/}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("ocaml",function(e){return{aliases:["ml"],k:{keyword:"and as assert asr begin class constraint do done downto else end exception external for fun function functor if in include inherit! inherit initializer land lazy let lor lsl lsr lxor match method!|10 method mod module mutable new object of open! open or private rec sig struct then to try type val! val virtual when while with parser value",built_in:"array bool bytes char exn|5 float int int32 int64 list lazy_t|5 nativeint|5 string unit in_channel out_channel ref",literal:"true false"},i:/\/\/|>>/,l:"[a-z_]\\w*!?",c:[{cN:"literal",b:"\\[(\\|\\|)?\\]|\\(\\)",r:0},e.C("\\(\\*","\\*\\)",{c:["self"]}),{cN:"symbol",b:"'[A-Za-z_](?!')[\\w']*"},{cN:"type",b:"`[A-Z][\\w']*"},{cN:"type",b:"\\b[A-Z][\\w']*",r:0},{b:"[a-z_]\\w*'[\\w']*",r:0},e.inherit(e.ASM,{cN:"string",r:0}),e.inherit(e.QSM,{i:null}),{cN:"number",b:"\\b(0[xX][a-fA-F0-9_]+[Lln]?|0[oO][0-7_]+[Lln]?|0[bB][01_]+[Lln]?|[0-9][0-9_]*([Lln]|(\\.[0-9_]*)?([eE][-+]?[0-9_]+)?)?)",r:0},{b:/[-=]>/}]}});hljs.registerLanguage("haskell",function(e){var i={v:[e.C("--","$"),e.C("{-","-}",{c:["self"]})]},a={cN:"meta",b:"{-#",e:"#-}"},l={cN:"meta",b:"^#",e:"$"},c={cN:"type",b:"\\b[A-Z][\\w']*",r:0},n={b:"\\(",e:"\\)",i:'"',c:[a,l,{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TM,{b:"[_a-z][\\w']*"}),i]},s={b:"{",e:"}",c:n.c};return{aliases:["hs"],k:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",c:[{bK:"module",e:"where",k:"module where",c:[n,i],i:"\\W\\.|;"},{b:"\\bimport\\b",e:"$",k:"import qualified as hiding",c:[n,i],i:"\\W\\.|;"},{cN:"class",b:"^(\\s*)?(class|instance)\\b",e:"where",k:"class family instance where",c:[c,n,i]},{cN:"class",b:"\\b(data|(new)?type)\\b",e:"$",k:"data family type newtype deriving",c:[a,c,n,s,i]},{bK:"default",e:"$",c:[c,n,i]},{bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{b:"\\bforeign\\b",e:"$",k:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",c:[c,e.QSM,i]},{cN:"meta",b:"#!\\/usr\\/bin\\/env runhaskell",e:"$"},a,l,e.QSM,e.CNM,c,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),i,{b:"->|<-"}]}});hljs.registerLanguage("objectivec",function(e){var t={cN:"built_in",b:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},_={keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},i=/[a-zA-Z@][a-zA-Z0-9_]*/,n="@interface @class @protocol @implementation";return{aliases:["mm","objc","obj-c"],k:_,l:i,i:""}]}]},{cN:"class",b:"("+n.split(" ").join("|")+")\\b",e:"({|$)",eE:!0,k:n,l:i,c:[e.UTM]},{b:"\\."+e.UIR,r:0}]}});hljs.registerLanguage("ruby",function(e){var b="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",r={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},c={cN:"doctag",b:"@[A-Za-z]+"},a={b:"#<",e:">"},s=[e.C("#","$",{c:[c]}),e.C("^\\=begin","^\\=end",{c:[c],r:10}),e.C("^__END__","\\n$")],n={cN:"subst",b:"#\\{",e:"}",k:r},t={cN:"string",c:[e.BE,n],v:[{b:/'/,e:/'/},{b:/"/,e:/"/},{b:/`/,e:/`/},{b:"%[qQwWx]?\\(",e:"\\)"},{b:"%[qQwWx]?\\[",e:"\\]"},{b:"%[qQwWx]?{",e:"}"},{b:"%[qQwWx]?<",e:">"},{b:"%[qQwWx]?/",e:"/"},{b:"%[qQwWx]?%",e:"%"},{b:"%[qQwWx]?-",e:"-"},{b:"%[qQwWx]?\\|",e:"\\|"},{b:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{b:/<<(-?)\w+$/,e:/^\s*\w+$/}]},i={cN:"params",b:"\\(",e:"\\)",endsParent:!0,k:r},d=[t,a,{cN:"class",bK:"class module",e:"$|;",i:/=/,c:[e.inherit(e.TM,{b:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{b:"<\\s*",c:[{b:"("+e.IR+"::)?"+e.IR}]}].concat(s)},{cN:"function",bK:"def",e:"$|;",c:[e.inherit(e.TM,{b:b}),i].concat(s)},{b:e.IR+"::"},{cN:"symbol",b:e.UIR+"(\\!|\\?)?:",r:0},{cN:"symbol",b:":(?!\\s)",c:[t,{b:b}],r:0},{cN:"number",b:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",r:0},{b:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{cN:"params",b:/\|/,e:/\|/,k:r},{b:"("+e.RSR+"|unless)\\s*",c:[a,{cN:"regexp",c:[e.BE,n],i:/\n/,v:[{b:"/",e:"/[a-z]*"},{b:"%r{",e:"}[a-z]*"},{b:"%r\\(",e:"\\)[a-z]*"},{b:"%r!",e:"![a-z]*"},{b:"%r\\[",e:"\\][a-z]*"}]}].concat(s),r:0}].concat(s);n.c=d,i.c=d;var l="[>?]>",o="[\\w#]+\\(\\w+\\):\\d+:\\d+>",u="(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>",w=[{b:/^\s*=>/,starts:{e:"$",c:d}},{cN:"meta",b:"^("+l+"|"+o+"|"+u+")",starts:{e:"$",c:d}}];return{aliases:["rb","gemspec","podspec","thor","irb"],k:r,i:/\/\*/,c:s.concat(w).concat(d)}});hljs.registerLanguage("cs",function(e){var i={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double else enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while nameof add alias ascending async await by descending dynamic equals from get global group into join let on orderby partial remove select set value var where yield",literal:"null false true"},r={cN:"string",b:'@"',e:'"',c:[{b:'""'}]},t=e.inherit(r,{i:/\n/}),a={cN:"subst",b:"{",e:"}",k:i},n=e.inherit(a,{i:/\n/}),c={cN:"string",b:/\$"/,e:'"',i:/\n/,c:[{b:"{{"},{b:"}}"},e.BE,n]},s={cN:"string",b:/\$@"/,e:'"',c:[{b:"{{"},{b:"}}"},{b:'""'},a]},o=e.inherit(s,{i:/\n/,c:[{b:"{{"},{b:"}}"},{b:'""'},n]});a.c=[s,c,r,e.ASM,e.QSM,e.CNM,e.CBCM],n.c=[o,c,t,e.ASM,e.QSM,e.CNM,e.inherit(e.CBCM,{i:/\n/})];var l={v:[s,c,r,e.ASM,e.QSM]},b=e.IR+"(<"+e.IR+"(\\s*,\\s*"+e.IR+")*>)?(\\[\\])?";return{aliases:["csharp"],k:i,i:/::/,c:[e.C("///","$",{rB:!0,c:[{cN:"doctag",v:[{b:"///",r:0},{b:""},{b:""}]}]}),e.CLCM,e.CBCM,{cN:"meta",b:"#",e:"$",k:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},l,e.CNM,{bK:"class interface",e:/[{;=]/,i:/[^\s:]/,c:[e.TM,e.CLCM,e.CBCM]},{bK:"namespace",e:/[{;=]/,i:/[^\s:]/,c:[e.inherit(e.TM,{b:"[a-zA-Z](\\.?\\w)*"}),e.CLCM,e.CBCM]},{bK:"new return throw await",r:0},{cN:"function",b:"("+b+"\\s+)+"+e.IR+"\\s*\\(",rB:!0,e:/[{;=]/,eE:!0,k:i,c:[{b:e.IR+"\\s*\\(",rB:!0,c:[e.TM],r:0},{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:i,r:0,c:[l,e.CNM,e.CBCM]},e.CLCM,e.CBCM]}]}});hljs.registerLanguage("typescript",function(e){var r={keyword:"in if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const class public private protected get set super static implements enum export import declare type namespace abstract",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document any number boolean string void"};return{aliases:["ts"],k:r,c:[{cN:"meta",b:/^\s*['"]use strict['"]/},e.ASM,e.QSM,{cN:"string",b:"`",e:"`",c:[e.BE,{cN:"subst",b:"\\$\\{",e:"\\}"}]},e.CLCM,e.CBCM,{cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM],r:0},{cN:"function",b:"function",e:/[\{;]/,eE:!0,k:r,c:["self",e.inherit(e.TM,{b:/[A-Za-z$_][0-9A-Za-z$_]*/}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}],i:/%/,r:0},{bK:"constructor",e:/\{/,eE:!0,c:["self",{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,k:r,c:[e.CLCM,e.CBCM],i:/["'\(]/}]},{b:/module\./,k:{built_in:"module"},r:0},{bK:"module",e:/\{/,eE:!0},{bK:"interface",e:/\{/,eE:!0,k:"interface extends"},{b:/\$[(.]/},{b:"\\."+e.IR,r:0},{cN:"meta",b:"@[A-Za-z]+"}]}});hljs.registerLanguage("elm",function(e){var i={v:[e.C("--","$"),e.C("{-","-}",{c:["self"]})]},t={cN:"type",b:"\\b[A-Z][\\w']*",r:0},c={b:"\\(",e:"\\)",i:'"',c:[{cN:"type",b:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},i]},n={b:"{",e:"}",c:c.c};return{k:"let in if then else case of where module import exposing type alias as infix infixl infixr port effect command subscription",c:[{bK:"port effect module",e:"exposing",k:"port effect module where command subscription exposing",c:[c,i],i:"\\W\\.|;"},{b:"import",e:"$",k:"import as exposing",c:[c,i],i:"\\W\\.|;"},{b:"type",e:"$",k:"type alias",c:[t,c,n,i]},{bK:"infix infixl infixr",e:"$",c:[e.CNM,i]},{b:"port",e:"$",k:"port",c:[i]},e.QSM,e.CNM,t,e.inherit(e.TM,{b:"^[_a-z][\\w']*"}),i,{b:"->|<-"}]}});hljs.registerLanguage("fsharp",function(e){var t={b:"<",e:">",c:[e.inherit(e.TM,{b:/'[a-zA-Z0-9_]+/})]};return{aliases:["fs"],k:"abstract and as assert base begin class default delegate do done downcast downto elif else end exception extern false finally for fun function global if in inherit inline interface internal lazy let match member module mutable namespace new null of open or override private public rec return sig static struct then to true try type upcast use val void when while with yield",i:/\/\*/,c:[{cN:"keyword",b:/\b(yield|return|let|do)!/},{cN:"string",b:'@"',e:'"',c:[{b:'""'}]},{cN:"string",b:'"""',e:'"""'},e.C("\\(\\*","\\*\\)"),{cN:"class",bK:"type",e:"\\(|=|$",eE:!0,c:[e.UTM,t]},{cN:"meta",b:"\\[<",e:">\\]",r:10},{cN:"symbol",b:"\\B('[A-Za-z])\\b",c:[e.BE]},e.CLCM,e.inherit(e.QSM,{i:null}),e.CNM]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b://,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}}); -------------------------------------------------------------------------------- /docs/assets/highlight/solarized-dark.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | Orginal Style from ethanschoonover.com/solarized (c) Jeremy Hull 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | background: #002b36; 12 | color: #839496; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #586e75; 18 | } 19 | 20 | /* Solarized Green */ 21 | .hljs-keyword, 22 | .hljs-selector-tag, 23 | .hljs-addition { 24 | color: #859900; 25 | } 26 | 27 | /* Solarized Cyan */ 28 | .hljs-number, 29 | .hljs-string, 30 | .hljs-meta .hljs-meta-string, 31 | .hljs-literal, 32 | .hljs-doctag, 33 | .hljs-regexp { 34 | color: #2aa198; 35 | } 36 | 37 | /* Solarized Blue */ 38 | .hljs-title, 39 | .hljs-section, 40 | .hljs-name, 41 | .hljs-selector-id, 42 | .hljs-selector-class { 43 | color: #268bd2; 44 | } 45 | 46 | /* Solarized Yellow */ 47 | .hljs-attribute, 48 | .hljs-attr, 49 | .hljs-variable, 50 | .hljs-template-variable, 51 | .hljs-class .hljs-title, 52 | .hljs-type { 53 | color: #b58900; 54 | } 55 | 56 | /* Solarized Orange */ 57 | .hljs-symbol, 58 | .hljs-bullet, 59 | .hljs-subst, 60 | .hljs-meta, 61 | .hljs-meta .hljs-keyword, 62 | .hljs-selector-attr, 63 | .hljs-selector-pseudo, 64 | .hljs-link { 65 | color: #cb4b16; 66 | } 67 | 68 | /* Solarized Red */ 69 | .hljs-built_in, 70 | .hljs-deletion { 71 | color: #dc322f; 72 | } 73 | 74 | .hljs-formula { 75 | background: #073642; 76 | } 77 | 78 | .hljs-emphasis { 79 | font-style: italic; 80 | } 81 | 82 | .hljs-strong { 83 | font-weight: bold; 84 | } 85 | -------------------------------------------------------------------------------- /docs/available-languages.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Purescript", 4 | "languageCode": "haskell" 5 | }, 6 | { 7 | "name": "Haskell", 8 | "languageCode": "haskell" 9 | }, 10 | { 11 | "name": "Elm", 12 | "languageCode": "elm" 13 | }, 14 | { 15 | "name": "F#", 16 | "languageCode": "fsharp" 17 | }, 18 | { 19 | "name": "Empty", 20 | "languageCode": "emptyslot" 21 | } 22 | ] 23 | -------------------------------------------------------------------------------- /docs/concepts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "name": "Forward function application", 4 | "description": "Apply / Pipe", 5 | "index": 0, 6 | "notes": "Applies an argument to a function. The Apply/Pipe-forward operator lets you pass an intermediate result onto the next function. The result of the left argument is passed as an argument to the right function. Data-oriented approach, more idiomatic in F# and Elm.", 7 | "languages": [ 8 | { 9 | "name": "Purescript", 10 | "code": "#, applyFlipped" 11 | }, 12 | { 13 | "name": "Haskell", 14 | "code": "&" 15 | }, 16 | { 17 | "name": "Elm", 18 | "code": "|>", 19 | "example": ["(|>) : a -> (a -> b) -> b", 20 | "", 21 | "employeeBossStreet : Employee -> String", 22 | "employeeBossStreet employee = employee", 23 | " |> boss", 24 | " |> address", 25 | " |> street", 26 | "", 27 | "employeeBossStreet dummyEmployeeRecord", 28 | ">\"DummyEmployeeBossStreetName\" : String." 29 | ] 30 | }, { 31 | "name": "F#", 32 | "code": "|>", 33 | "example": ["( |> ) : 'T1 -> ('T1 -> 'U) -> 'U ", 34 | "", 35 | "let employeeBossStreet (employee: Employee) : string = ", 36 | " employee", 37 | " |> boss", 38 | " |> address", 39 | " |> street", 40 | "", 41 | "employeeBossStreet dummyEmployeeRecord", 42 | ">val it : string = \"DummyEmployeeBossStreetName\"" 43 | ] 44 | } 45 | ], 46 | "links": [ 47 | { 48 | "url": "https://pursuit.purescript.org/packages/purescript-prelude/2.1.0/docs/Prelude#v:(#)", 49 | "description": "Purescript # reference" 50 | }, 51 | { 52 | "url": "http://stackoverflow.com/questions/1457140/haskell-composition-vs-fs-pipe-forward-operator", 53 | "description": "Stack Overflow discussion" 54 | }, 55 | { 56 | "url": "http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#|>", 57 | "description": "Elm Basics - (|>)" 58 | }, 59 | { 60 | "url": "https://www.reddit.com/r/haskell/comments/3mttyh/elms_operator/", 61 | "description": "A discussion on idiomatic operators in Elm and Haskell" 62 | } 63 | ] 64 | }, 65 | { 66 | "name": "Backward function application", 67 | "description": "Apply / Pipe", 68 | "index": 1, 69 | "notes": "Applies a function to an argument. Can be used to avoid parentheses and improve readability. The result of the right argument is applied to the left argument.", 70 | "languages": [ 71 | { 72 | "name": "Purescript", 73 | "code": "$, apply", 74 | "example": ["apply :: forall a b. (a -> b) -> a -> b", 75 | "apply f x = f x", 76 | "", 77 | "--without operator", 78 | "employeeBossStreet :: Employee -> String", 79 | "employeeBossStreet employee =", 80 | " street (address (boss employee))", 81 | "employeeBossStreet dummyEmployeeRecord", 82 | ">\"DummyEmployeeBossStreetName\"", 83 | "", 84 | "--with operator", 85 | "employeeBossStreet :: Employee -> String", 86 | "employeeBossStreet employee =", 87 | " street $ address $ boss employee", 88 | "employeeBossStreet dummyEmployeeRecord", 89 | ">\"DummyEmployeeBossStreetName\"" 90 | ] 91 | }, 92 | { 93 | "name": "Haskell", 94 | "code": "$", 95 | "example": ["($) :: (a -> b) -> a -> b", 96 | "F x = f x", 97 | "", 98 | "= street (address (boss employee))", 99 | "= street $ address $ boss employee" 100 | ] 101 | }, 102 | { 103 | "name": "Elm", 104 | "code": "<|", 105 | "example": ["(<|) : (a -> b) -> a -> b", 106 | "", 107 | "--without operator", 108 | "employeeBossStreet : Employee -> String", 109 | "employeeBossStreet employee = ", 110 | " street (address (boss employee))", 111 | "", 112 | "employeeBossStreet dummyEmployeeRecord", 113 | ">\"DummyEmployeeBossStreetName\" : String. ", 114 | "", 115 | "-- with operator", 116 | "employeeBossStreet : Employee -> String", 117 | "employeeBossStreet employee = ", 118 | " street <| address <| boss employee", 119 | "", 120 | "employeeBossStreet dummyEmployeeRecord", 121 | ">\"DummyEmployeeBossStreetName\" : String." 122 | ] 123 | }, { 124 | "name": "F#", 125 | "code": "<|", 126 | "example": [ "( <| ) : ('T -> 'U) -> 'T -> 'U", 127 | "", 128 | "//without operator", 129 | "let employeeBossStreet (employee: Employee) : string =", 130 | " street (address (boss employee))", 131 | "", 132 | "employeeBossStreet dummyEmployeeRecord", 133 | ">val it : string = \"DummyEmployeeBossStreetName\" ", 134 | "", 135 | "//with operator", 136 | "let employeeBossStreet (employee: Employee) : string =", 137 | " street <| address <| boss employee", 138 | "", 139 | "employeeBossStreet dummyEmployeeRecord", 140 | ">val it : string = \"DummyEmployeeBossStreetName\"" 141 | ] 142 | } 143 | ], 144 | "links": [ 145 | { 146 | "url": "https://pursuit.purescript.org/packages/purescript-prelude/2.1.0/docs/Prelude#v:($)", 147 | "description": "Purescript $ reference" 148 | }, 149 | { 150 | "url": "http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#<|", 151 | "description": "Elm Basics - (<|)" 152 | }, 153 | { 154 | "url": "https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/functions/index", 155 | "description": "F# functions reference" 156 | }, 157 | { 158 | "url": "https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/symbol-and-operator-reference/", 159 | "description": "F# operator reference" 160 | } 161 | ] 162 | }, 163 | { 164 | "name": "Composition - forward", 165 | "description": "Forward/right", 166 | "notes": "Creating a new, combined function by piping the result of the left argument to the right argument. A function-oriented approach, combining functions first, actual values input later.", 167 | "index": 2, 168 | "languages": [ 169 | { 170 | "name": "Purescript", 171 | "code": ">>>, composeFlipped", 172 | "example": ["composeFlipped :: forall a b c d. Semigroupoid a => a b c -> a c d -> a b d", 173 | "", 174 | "employeeBossStreet :: (Employee -> String)", 175 | "employeeBossStreet =", 176 | " boss >>> address >>> street", 177 | "", 178 | "employeeBossStreet dummyEmployeeRecord", 179 | ">\"DummyEmployeeBossStreetName\"" 180 | ] 181 | 182 | }, 183 | { 184 | "name": "Haskell", 185 | "code": ">>>", 186 | "example": ["employeeBossStreet = (boss >>> address >>> street) employee" 187 | ] 188 | }, 189 | { 190 | "name": "Elm", 191 | "code": ">>", 192 | "example": ["(>>) : (a -> b) -> (b -> c) -> a -> c", 193 | "", 194 | "employeeBossStreet : (Employee -> String)", 195 | "employeeBossStreet =", 196 | " boss >> address >> street", 197 | "", 198 | "employeeBossStreet dummyEmployeeRecord", 199 | ">\"DummyEmployeeBossStreetName\" : String." 200 | ] 201 | }, 202 | { 203 | "name": "F#", 204 | "code": ">>", 205 | "example": ["(>>) : ('a -> 'b) -> ('b -> 'c) -> 'a -> 'c", 206 | "", 207 | "let employeeBossStreet : (Employee -> string) =", 208 | " boss >> address >> street", 209 | "", 210 | "employeeBossStreet dummyEmployeeRecord", 211 | ">val it : string = \"DummyEmployeeBossStreetName\"" 212 | ] 213 | } 214 | ], 215 | "links": [ 216 | { 217 | "url": "https://wiki.haskell.org/Function_composition", 218 | "description": "Haskell wiki" 219 | }, 220 | { 221 | "url": "https://fsharpforfunandprofit.com/posts/function-composition/", 222 | "description": "F# for fun and profilt - function composition" 223 | }, 224 | { 225 | "url": "http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#>>", 226 | "description": "Elm - basics >>" 227 | } 228 | ] 229 | }, 230 | { 231 | "name": "Composition - backward", 232 | "description": "Backward/left", 233 | "notes": "Creating a new, combined function by piping the result of the right argument to the left argument. A function-oriented approach, combining functions first, actual values input later. More idiomatic in Purescript/Haskell. The Control.Arrow module in Haskell base has (<<<) in addition to (>>>). For function arrows, (<<<) specializes to (.).", 234 | "index": 3, 235 | "languages": [ 236 | { 237 | "name": "Purescript", 238 | "code": "<<<, compose", 239 | "example": ["compose :: forall a b c. (b -> c) -> (a -> b) -> a -> c", 240 | "", 241 | "employeeBossStreet :: (Employee -> String)", 242 | "employeeBossStreet =", 243 | " street <<< address <<< boss", 244 | "", 245 | "employeeBossStreet dummyEmployeeRecord", 246 | ">\"DummyEmployeeBossStreetName\"" 247 | ] 248 | }, 249 | { 250 | "name": "Haskell", 251 | "code": "<<<, .", 252 | "example": ["employeeBossStreet = (street . address . boss) employee", 253 | "", 254 | "employeeBossStreet = (street <<< address <<< boss) employee" 255 | ] 256 | }, 257 | { 258 | "name": "Elm", 259 | "code": "<<", 260 | "example": ["(<<) : (b -> c) -> (a -> b) -> a -> c", 261 | "", 262 | "employeeBossStreet : (Employee -> String)", 263 | "employeeBossStreet =", 264 | " street << address << boss", 265 | "", 266 | "employeeBossStreet dummyEmployeeRecord", 267 | ">\"DummyEmployeeBossStreetName\" : String." 268 | ] 269 | }, 270 | { 271 | "name": "F#", 272 | "code": "<<", 273 | "example": ["(<<) : ('b -> 'c) -> ('a -> 'b) -> 'a -> 'c", 274 | "", 275 | "let employeeBossStreet : (Employee -> string) =", 276 | " street << address << boss", 277 | "", 278 | "employeeBossStreet dummyEmployeeRecord", 279 | ">val it : string = \"DummyEmployeeBossStreetName\"" 280 | ] 281 | } 282 | ], 283 | "links": [ 284 | { 285 | "url": "https://wiki.haskell.org/Function_composition", 286 | "description": "Haskell wiki" 287 | }, 288 | { 289 | "url": "https://fsharpforfunandprofit.com/posts/function-composition/", 290 | "description": "F# for fun and profilt - function composition" 291 | }, 292 | { 293 | "url": "http://package.elm-lang.org/packages/elm-lang/core/latest/Basics#<<", 294 | "description": "Elm - basics (<<)" 295 | } 296 | ] 297 | }, 298 | { 299 | "name": "Unit type", 300 | "description": "Empty", 301 | "index": 3, 302 | "languages": [ 303 | { 304 | "name": "Purescript", 305 | "code": "Unit" 306 | }, 307 | { 308 | "name": "Haskell", 309 | "code": "()" 310 | }, 311 | { 312 | "name": "Elm", 313 | "code": "()" 314 | }, { 315 | "name": "F#", 316 | "code": "()" 317 | } 318 | ] 319 | }, 320 | { 321 | "name": "Anonymous function", 322 | "description": "Lambda", 323 | "index": 3, 324 | "languages": [ 325 | { 326 | "name": "Purescript", 327 | "code": "\\x -> x + 1" 328 | }, 329 | { 330 | "name": "Haskell", 331 | "code": "\\x -> x + 1" 332 | }, 333 | { 334 | "name": "Elm", 335 | "code": "\\x -> x + 1" 336 | }, { 337 | "name": "F#", 338 | "code": "fun x -> x + 1" 339 | } 340 | ] 341 | }, 342 | { 343 | "name": "Identity function", 344 | "description": "", 345 | "index": 3, 346 | "languages": [ 347 | { 348 | "name": "Purescript", 349 | "code": "id" 350 | }, 351 | { 352 | "name": "Haskell", 353 | "code": "id" 354 | }, 355 | { 356 | "name": "Elm", 357 | "code": "identity" 358 | }, { 359 | "name": "F#", 360 | "code": "id" 361 | } 362 | ] 363 | }, 364 | { 365 | "name": "Tuple", 366 | "description": "Definition", 367 | "index": 3, 368 | "languages": [ 369 | { 370 | "name": "Purescript", 371 | "code": "Tuple a b" 372 | }, 373 | { 374 | "name": "Haskell", 375 | "code": "(Int, String)" 376 | }, 377 | { 378 | "name": "Elm", 379 | "code": "(Int, String)" 380 | }, { 381 | "name": "F#", 382 | "code": "int * string" 383 | } 384 | ] 385 | }, 386 | { "name": "Tuple", 387 | "description": "Usage", 388 | "index": 3, 389 | "languages": [ 390 | { 391 | "name": "Purescript", 392 | "code": "Tuple 2 \"Test\"" 393 | }, 394 | { 395 | "name": "Haskell", 396 | "code": "(2, \"Test\")" 397 | }, 398 | { 399 | "name": "Elm", 400 | "code": "(2, \"Test\")" 401 | }, { 402 | "name": "F#", 403 | "code": "(2, \"Test\")" 404 | } 405 | ] 406 | }, 407 | { 408 | "name": "Record types", 409 | "description": "", 410 | "index": 3, 411 | "languages": [ 412 | { 413 | "name": "Purescript", 414 | "code": "type Point = { x :: Int, y :: Int}" 415 | }, 416 | { 417 | "name": "Haskell", 418 | "code": "data Point = Point { x :: Int, y :: Int}" 419 | }, 420 | { 421 | "name": "Elm", 422 | "code": "type alias Point = { x : Int, y : Int}" 423 | }, { 424 | "name": "F#", 425 | "code": "type Point = {\r x : int; y : int}" 426 | } 427 | ] 428 | }, 429 | { 430 | "name": "Union types", 431 | "description": "Sum types / Discriminated unions / Algebraic data types (ADT)", 432 | "index": 3, 433 | "languages": [ 434 | { 435 | "name": "Purescript", 436 | "code": "data Shape Circle Point Int | Line Point Point" 437 | }, 438 | { 439 | "name": "Haskell", 440 | "code": "data Shape = Circle Point Int | Line Point Point" 441 | }, 442 | { 443 | "name": "Elm", 444 | "code": "type Shape = Circle Point Int | Line Point Point" 445 | }, { 446 | "name": "F#", 447 | "code": "type Shape = Circle of Point * int | Line of Point * Point" 448 | } 449 | ] 450 | }, 451 | { 452 | "name": "Maybe/Option", 453 | "description": "", 454 | "index": 3, 455 | "languages": [ 456 | { 457 | "name": "Purescript", 458 | "code": "data Maybe a = Just a | Nothing" 459 | }, 460 | { 461 | "name": "Haskell", 462 | "code": "data Maybe a = Just a | Nothing" 463 | }, 464 | { 465 | "name": "Elm", 466 | "code": "type Maybe a = Just a | Nothing" 467 | }, { 468 | "name": "F#", 469 | "code": "type Option<'a> = | Some of 'a | None" 470 | } 471 | ] 472 | }, 473 | { 474 | "name": "Either / Result", 475 | "description": "", 476 | "index": 3, 477 | "languages": [ 478 | { 479 | "name": "Purescript", 480 | "code": "data Either a b = Left a | Right b" 481 | }, 482 | { 483 | "name": "Haskell", 484 | "code": "data Either a b = Left a | Right b" 485 | }, 486 | { 487 | "name": "Elm", 488 | "code": "type Result error value = Ok value | Err error" 489 | }, { 490 | "name": "F#", 491 | "code": "(in F# 4.1) type Result<'T,'TError> = | Ok of 'T | Error of 'TError" 492 | } 493 | ] 494 | }, 495 | { 496 | "name": "Functor map", 497 | "description": "Map", 498 | "index": 3, 499 | "languages": [ 500 | { 501 | "name": "Purescript", 502 | "code": "<$>, map" 503 | }, 504 | { 505 | "name": "Haskell", 506 | "code": "<$>, fmap" 507 | }, 508 | { 509 | "name": "Elm", 510 | "code": "map" 511 | }, { 512 | "name": "F#", 513 | "code": "map" 514 | } 515 | ] 516 | }, 517 | { 518 | "name": "Functor apply", 519 | "description": "Apply", 520 | "notes" : "*andMap is not core in Elm, but is often used in Packages.", 521 | "index": 3, 522 | "languages": [ 523 | { 524 | "name": "Purescript", 525 | "code": "<*>, apply" 526 | }, 527 | { 528 | "name": "Haskell", 529 | "code": "<*>" 530 | }, 531 | { 532 | "name": "Elm", 533 | "code": "andMap(*notes)" 534 | }, { 535 | "name": "F#", 536 | "code": "apply" 537 | } 538 | ], 539 | "links": [ 540 | { 541 | "url": "http://klaftertief.github.io/elm-search/?q=andMap", 542 | "description": "Elm - External packages using andMap" 543 | } 544 | ] 545 | }, 546 | { 547 | "name": "Functor lift", 548 | "description": "", 549 | "index": 3, 550 | "languages": [ 551 | { 552 | "name": "Purescript", 553 | "code": "liftN" 554 | }, 555 | { 556 | "name": "Haskell", 557 | "code": "liftN" 558 | }, 559 | { 560 | "name": "Elm", 561 | "code": "mapN" 562 | }, { 563 | "name": "F#", 564 | "code": "mapN" 565 | } 566 | ] 567 | }, 568 | { 569 | "name": "Bind", 570 | "description": "", 571 | "index": 3, 572 | "languages": [ 573 | { 574 | "name": "Purescript", 575 | "code": ">>=, bind" 576 | }, 577 | { 578 | "name": "Haskell", 579 | "code": ">>=" 580 | }, 581 | { 582 | "name": "Elm", 583 | "code": "andThen" 584 | }, { 585 | "name": "F#", 586 | "code": "bind" 587 | } 588 | ] 589 | }, 590 | { 591 | "name": "Comments", 592 | "description": "", 593 | "index": 3, 594 | "notes": "Single line comments, block comments and documentation comments.", 595 | "languages": [ 596 | { 597 | "name": "Purescript", 598 | "code": "-- Line {- Block -} --| Documentation", 599 | "example": ["-- A single line comment", 600 | "{-", 601 | " Comment", 602 | " continued comment {- Nested block -}", 603 | "-}", 604 | "-- | Comments that start with a pipe character, |, are considered documentation, and will appear in the output of tools like psc-docs and Pursuit.", 605 | "-- | Adds two numbers", 606 | "-- This comment does not start with a pipe and will not be part of the documentation", 607 | "add :: Int -> Int -> Int", 608 | "add x y = x + y" 609 | ] 610 | }, 611 | { 612 | "name": "Haskell", 613 | "code": "-- Line {- Block -} --| Documentation", 614 | "example": ["-- A single line comment", 615 | "{-", 616 | " Comment", 617 | " continued comment {- Nested block -}", 618 | "-}", 619 | "-- | Comments that start with a pipe character, |, are considered documentation, and will appear in the output of documentation tools.", 620 | "-- | Adds two numbers", 621 | "add :: Int -> Int -> Int", 622 | "add x y = x + y" 623 | ] 624 | }, 625 | { 626 | "name": "Elm", 627 | "code": "-- Line {- Block -}", 628 | "example": ["-- A single line comment", 629 | "{-", 630 | " Comment", 631 | " continued comment {- Nested block -}", 632 | "-}", 633 | "{- Block comments that start with a pipe character, |, are ", 634 | "considered documentation, and will", 635 | "appear in the output package documentation.", 636 | "", 637 | "@docs add", 638 | "To output documentation, @docs keyword precedes a comma-separated list of values", 639 | "The @docs add, will document the comment preceeding the add function.", 640 | "-}", 641 | "{-|", 642 | "Adds two numbers", 643 | "-}", 644 | "add : Int -> Int -> Int", 645 | "add x y = x + y" 646 | ] 647 | }, { 648 | "name": "F#", 649 | "code": "// Line (* Block *)", 650 | "example": ["// A single line comment", 651 | "(*", 652 | " Comment", 653 | " continued comment", 654 | "*)", 655 | "// XML documentation comments come after ///", 656 | "/// Adds two numbers", 657 | "let add (x:int) (y:int) = x + y" 658 | ] 659 | } 660 | ], 661 | "links": [ 662 | { 663 | "url": "https://github.com/purescript/documentation/blob/master/language/Syntax.md#comments", 664 | "description": "Purescript comments" 665 | }, 666 | { 667 | "url": "http://elm-lang.org/docs/syntax#comments", 668 | "description": "Elm comments" 669 | }, 670 | { 671 | "url": "http://package.elm-lang.org/help/documentation-format", 672 | "description": "Elm package documentation" 673 | }, 674 | { 675 | "url": "https://dungpa.github.io/fsharp-cheatsheet/", 676 | "description": "F# Cheatsheet" 677 | }, 678 | { 679 | "url": "https://wiki.haskell.org/Reference_card#Comments", 680 | "description": "Haskell reference card" 681 | } 682 | ] 683 | }, 684 | { 685 | "name": "Type annotation", 686 | "description": "Function definition", 687 | "index": 3, 688 | "notes": "Annotating types can in many situations be omitted due to type inference, but can improve readability.", 689 | "languages": [ 690 | { 691 | "name": "Purescript", 692 | "code": "add :: Int -> Int -> Int", 693 | "example": ["add :: Int -> Int -> Int", 694 | "add x y = x + y", 695 | "", 696 | "-- Using universally quantified types (generic)", 697 | "flip :: forall a b c. (a -> b -> c) -> b -> a -> c", 698 | "flip f b a = f a b" 699 | ] 700 | }, 701 | { 702 | "name": "Haskell", 703 | "code": "add :: Int -> Int -> Int", 704 | "example": ["add :: Int -> Int -> Int", 705 | "add x y = x + y", 706 | "", 707 | "-- Using generic types (any type)", 708 | "flip :: (a -> b -> c) -> b -> a -> c", 709 | "flip f b a = f a b" 710 | ] 711 | }, 712 | { 713 | "name": "Elm", 714 | "code": "add : Int -> Int -> Int", 715 | "example": ["add : Int -> Int -> Int", 716 | "add x y = x + y", 717 | "", 718 | "-- Using generic types (any type)", 719 | "flip : (a -> b -> c) -> b -> a -> c", 720 | "flip f b a = f a b" 721 | ] 722 | }, { 723 | "name": "F#", 724 | "code": "let add (x:int) (y:int) : int = x + y", 725 | "example": ["let add (x:int) (y:int) : int = x + y" 726 | ] 727 | } 728 | ], 729 | "links": [ 730 | { 731 | "url": "http://elm-lang.org/docs/syntax#type-annotations", 732 | "description": "Elm type annnotations" 733 | }, 734 | { 735 | "url": "https://fsharpforfunandprofit.com/posts/function-signatures/", 736 | "description": "F# for fun and profit function signatures" 737 | }, 738 | { 739 | "url": "http://learnyouahaskell.com/types-and-typeclasses", 740 | "description": "Haskell types and typeclasses" 741 | } 742 | ] 743 | }, 744 | { 745 | "name": "Generic types", 746 | "description": "Type variables", 747 | "index": 3, 748 | "notes": "Generic functions and types enable you to write code that works with a variety of types without repeating the code for each type. Type variables/generic types can have names longer than one character, but usually given one character names.", 749 | "languages": [ 750 | { 751 | "name": "Purescript", 752 | "code": "forall a b.", 753 | "example": ["-- Any lowercase identifier can be used, like a, msg.", 754 | "flip :: forall a b c. (a -> b -> c) -> b -> a -> c" 755 | ] 756 | }, 757 | { 758 | "name": "Haskell", 759 | "code": "a b", 760 | "example": ["-- Any lowercase identifier can be used, like a, msg.", 761 | "flip :: (a -> b -> c) -> b -> a -> c" 762 | ] 763 | }, 764 | { 765 | "name": "Elm", 766 | "code": "a b", 767 | "example": ["-- Any lowercase identifier can be used, like a, msg.", 768 | "flip : (a -> b -> c) -> b -> a -> c" 769 | ] 770 | }, { 771 | "name": "F#", 772 | "code": "'a 'b 'C", 773 | "example": ["// Generics are identified by ' and can use upper/lowercase, like 'a, 'Msg.", 774 | "val flip = ('a -> 'b -> 'c) -> 'b -> 'a -> 'c", 775 | "// Can also use x y =", 777 | " printfn \"%A, %A\" x y" 778 | ] 779 | } 780 | ], 781 | "links": [ 782 | { 783 | "url": "https://www.tutorialspoint.com/fsharp/fsharp_generics.htm", 784 | "description": "F# Generics" 785 | }, 786 | { 787 | "url": "https://docs.microsoft.com/en-us/dotnet/articles/fsharp/language-reference/generics/", 788 | "description": "F# Generics - Microsoft F# language reference" 789 | }, 790 | { 791 | "url": "https://www.elm-tutorial.org/en/01-foundations/03-functions-2.html", 792 | "description": "Elm tutorial - functions" 793 | } 794 | ] 795 | } 796 | ] 797 | -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakonrossebo/functional-programming-babelfish/e54a5eebcc731074fa47e4e6aa932378e5a7c5dd/docs/favicon.ico -------------------------------------------------------------------------------- /docs/images/elm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakonrossebo/functional-programming-babelfish/e54a5eebcc731074fa47e4e6aa932378e5a7c5dd/docs/images/elm.png -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | Functional programming Babelfish
-------------------------------------------------------------------------------- /elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "Viewer for Functional Babelfish concepts", 4 | "repository": "https://github.com/hakonrossebo/functional-programming-babelfish.git", 5 | "license": "MIT", 6 | "source-directories": [ 7 | "./src" 8 | ], 9 | "exposed-modules": [], 10 | "dependencies": { 11 | "debois/elm-mdl": "8.1.0 <= v < 9.0.0", 12 | "elm-lang/core": "5.0.0 <= v < 6.0.0", 13 | "elm-lang/html": "2.0.0 <= v < 3.0.0", 14 | "elm-lang/http": "1.0.0 <= v < 2.0.0", 15 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0", 16 | "elm-lang/svg": "2.0.0 <= v < 3.0.0", 17 | "evancz/elm-markdown": "3.0.1 <= v < 4.0.0", 18 | "evancz/url-parser": "2.0.1 <= v < 3.0.0", 19 | "krisajenkins/remotedata": "4.3.0 <= v < 5.0.0", 20 | "sporto/elm-dropdown": "1.2.2 <= v < 2.0.0" 21 | }, 22 | "elm-version": "0.18.0 <= v < 0.19.0" 23 | } 24 | -------------------------------------------------------------------------------- /images/elm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakonrossebo/functional-programming-babelfish/e54a5eebcc731074fa47e4e6aa932378e5a7c5dd/images/elm.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "functionalprogrammingbabelfish", 3 | "version": "1.0.0", 4 | "description": "A viewer for functional programming concepts in different languages", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --inline", 8 | "build": "webpack --config webpack.config.prod.js" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "MIT", 13 | "devDependencies": { 14 | "clean-webpack-plugin": "^0.1.16", 15 | "css-loader": "^0.27.3", 16 | "elm": "^0.18.0", 17 | "elm-hot-loader": "^0.5.4", 18 | "elm-webpack-loader": "^4.1.1", 19 | "file-loader": "^0.10.1", 20 | "html-webpack-plugin": "2.24.1", 21 | "style-loader": "^0.14.0", 22 | "webpack": "1.14.0", 23 | "webpack-dev-server": "1.16.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/CustomPorts.elm: -------------------------------------------------------------------------------- 1 | port module CustomPorts exposing (..) 2 | 3 | port scrollIdIntoView : String -> Cmd msg 4 | -------------------------------------------------------------------------------- /src/Decoders.elm: -------------------------------------------------------------------------------- 1 | module Decoders exposing (..) 2 | 3 | import Types exposing (..) 4 | import Json.Decode as Json exposing (field) 5 | 6 | 7 | decodeAvailableLanguages : Json.Decoder (List Language) 8 | decodeAvailableLanguages = 9 | Json.list decodeLanguage 10 | 11 | 12 | decodeLanguage : Json.Decoder Language 13 | decodeLanguage = 14 | Json.map2 Language 15 | (field "name" Json.string) 16 | (field "languageCode" Json.string) 17 | 18 | 19 | decodeConcepts : Json.Decoder (List Concept) 20 | decodeConcepts = 21 | Json.list decodeConcept 22 | 23 | 24 | decodeConcept : Json.Decoder Concept 25 | decodeConcept = 26 | Json.map6 Concept 27 | (field "name" Json.string) 28 | (field "description" Json.string) 29 | (field "index" Json.int) 30 | ((Json.maybe (field "notes" Json.string)) |> Json.andThen decodeSuccessNotes) 31 | (field "languages" decodeConceptLanguageImplementations) 32 | ((Json.maybe (field "links" decodeConceptLinks)) |> Json.andThen decodeSuccessLinks) 33 | 34 | 35 | nullable : Json.Decoder a -> Json.Decoder (Maybe a) 36 | nullable decoder = 37 | Json.oneOf 38 | [ Json.null Nothing 39 | , Json.map Just decoder 40 | ] 41 | 42 | 43 | decodeSuccessNotes : Maybe String -> Json.Decoder (Maybe String) 44 | decodeSuccessNotes notes = 45 | Json.succeed (Maybe.withDefault Nothing (Just notes)) 46 | 47 | 48 | decodeSuccessLinks : Maybe (List ConceptLink) -> Json.Decoder (List ConceptLink) 49 | decodeSuccessLinks links = 50 | Json.succeed (Maybe.withDefault [] links) 51 | 52 | 53 | decodeConceptLanguageImplementations : Json.Decoder (List LanguageImplementation) 54 | decodeConceptLanguageImplementations = 55 | Json.list decodeLanguageImplementation 56 | 57 | 58 | decodeLanguageImplementation : Json.Decoder LanguageImplementation 59 | decodeLanguageImplementation = 60 | Json.map3 LanguageImplementation 61 | (field "name" Json.string) 62 | (field "code" Json.string) 63 | ((Json.maybe (field "example" (Json.list Json.string))) |> Json.andThen decodeSuccessExample) 64 | 65 | 66 | decodeSuccessExample : Maybe (List String) -> Json.Decoder (Maybe (List String)) 67 | decodeSuccessExample example = 68 | Json.succeed (Maybe.withDefault Nothing (Just example)) 69 | 70 | 71 | decodeConceptLinks : Json.Decoder (List ConceptLink) 72 | decodeConceptLinks = 73 | Json.list decodeConceptLink 74 | 75 | 76 | decodeConceptLink : Json.Decoder ConceptLink 77 | decodeConceptLink = 78 | Json.map2 ConceptLink 79 | (field "url" Json.string) 80 | (field "description" Json.string) 81 | -------------------------------------------------------------------------------- /src/Main.elm: -------------------------------------------------------------------------------- 1 | module Main exposing (..) 2 | 3 | import Navigation exposing (Location) 4 | import Html exposing (..) 5 | import Types exposing (..) 6 | import Time exposing (Time) 7 | import RemoteData exposing (RemoteData(..)) 8 | import Routing.Router as Router 9 | import Http 10 | import Decoders 11 | import Material.Menu as Menu 12 | import Material 13 | import Material.Progress as Loading 14 | import Material.Options as Options exposing (when, css, cs, Style, onClick) 15 | 16 | 17 | main : Program Flags Model Msg 18 | main = 19 | Navigation.programWithFlags UrlChange 20 | { init = init 21 | , update = update 22 | , view = view 23 | , subscriptions = subscriptions 24 | } 25 | 26 | 27 | subscriptions : Model -> Sub Msg 28 | subscriptions model = 29 | let 30 | childSubscriptions = 31 | case model.appState of 32 | Ready taco routerModel -> 33 | Sub.map RouterMsg (Router.subs routerModel) 34 | 35 | NotReady _ -> 36 | Sub.none 37 | in 38 | Sub.batch 39 | [ Time.every Time.minute TimeChange 40 | , childSubscriptions 41 | , Material.subscriptions Mdl model 42 | ] 43 | 44 | 45 | type alias Model = 46 | { mdl : Material.Model 47 | , appState : AppState 48 | , location : Location 49 | } 50 | 51 | 52 | type AppState 53 | = NotReady Time 54 | | Ready Taco Router.Model 55 | 56 | 57 | type alias Flags = 58 | { currentTime : Time 59 | } 60 | 61 | 62 | type Msg 63 | = Mdl (Material.Msg Msg) 64 | | UrlChange Location 65 | | TimeChange Time 66 | | RouterMsg Router.Msg 67 | | HandleAvailableLanguagesResponse (RemoteData.WebData (List Language)) 68 | 69 | 70 | init : Flags -> Location -> ( Model, Cmd Msg ) 71 | init flags location = 72 | ( { mdl = Material.model 73 | , appState = NotReady flags.currentTime 74 | , location = location 75 | } 76 | , fetchAvailableLanguages 77 | ) 78 | 79 | 80 | fetchAvailableLanguages : Cmd Msg 81 | fetchAvailableLanguages = 82 | let 83 | url = 84 | "available-languages.json" 85 | 86 | req = 87 | Http.request 88 | { method = "GET" 89 | , headers = [] 90 | , url = url 91 | , body = Http.emptyBody 92 | , expect = Http.expectJson Decoders.decodeAvailableLanguages 93 | , timeout = Nothing 94 | , withCredentials = False 95 | } 96 | in 97 | req 98 | |> RemoteData.sendRequest 99 | |> Cmd.map HandleAvailableLanguagesResponse 100 | 101 | 102 | update : Msg -> Model -> ( Model, Cmd Msg ) 103 | update msg model = 104 | case msg of 105 | Mdl msg_ -> 106 | Material.update Mdl msg_ model 107 | 108 | TimeChange time -> 109 | updateTime model time 110 | 111 | HandleAvailableLanguagesResponse webData -> 112 | updateAvailableLanguages model webData 113 | 114 | UrlChange location -> 115 | updateRouter { model | location = location } (Router.UrlChange location) 116 | 117 | RouterMsg routerMsg -> 118 | updateRouter model routerMsg 119 | 120 | 121 | updateTime : Model -> Time -> ( Model, Cmd Msg ) 122 | updateTime model time = 123 | case model.appState of 124 | NotReady _ -> 125 | ( { model | appState = NotReady time } 126 | , Cmd.none 127 | ) 128 | 129 | Ready taco routerModel -> 130 | ( { model | appState = Ready (updateTaco taco (UpdateTime time)) routerModel } 131 | , Cmd.none 132 | ) 133 | 134 | 135 | updateRouter : Model -> Router.Msg -> ( Model, Cmd Msg ) 136 | updateRouter model routerMsg = 137 | case model.appState of 138 | Ready taco routerModel -> 139 | let 140 | nextTaco = 141 | updateTaco taco tacoUpdate 142 | 143 | ( nextRouterModel, routerCmd, tacoUpdate ) = 144 | Router.update routerMsg routerModel 145 | in 146 | ( { model | appState = Ready nextTaco nextRouterModel } 147 | , Cmd.map RouterMsg routerCmd 148 | ) 149 | 150 | NotReady _ -> 151 | Debug.crash "Ooops. We got a sub-component message even though it wasn't supposed to be initialized?!?!?" 152 | 153 | 154 | updateAvailableLanguages : Model -> RemoteData.WebData (List Language) -> ( Model, Cmd Msg ) 155 | updateAvailableLanguages model webData = 156 | case webData of 157 | Failure _ -> 158 | Debug.crash "OMG CANT EVEN DOWNLOAD." 159 | 160 | Success languages -> 161 | case model.appState of 162 | NotReady time -> 163 | let 164 | initTaco = 165 | { currentTime = time 166 | , availableLanguages = languages 167 | } 168 | 169 | ( initRouterModel, routerCmd ) = 170 | Router.init model.location initTaco 171 | in 172 | ( { model | appState = Ready initTaco initRouterModel } 173 | , Cmd.map RouterMsg routerCmd 174 | ) 175 | 176 | Ready taco routerModel -> 177 | ( { model | appState = Ready (updateTaco taco (UpdateAvailableLanguages languages)) routerModel } 178 | , Cmd.none 179 | ) 180 | 181 | _ -> 182 | ( model, Cmd.none ) 183 | 184 | 185 | updateTaco : Taco -> TacoUpdate -> Taco 186 | updateTaco taco tacoUpdate = 187 | case tacoUpdate of 188 | UpdateTime time -> 189 | { taco | currentTime = time } 190 | 191 | UpdateAvailableLanguages languages -> 192 | { taco | availableLanguages = Debug.log "languages" languages } 193 | 194 | NoUpdate -> 195 | taco 196 | 197 | 198 | view : Model -> Html Msg 199 | view model = 200 | case model.appState of 201 | Ready taco routerModel -> 202 | Router.view taco routerModel 203 | |> Html.map RouterMsg 204 | 205 | NotReady _ -> 206 | Options.div 207 | [ css "display" "flex" 208 | , css "width" "100%" 209 | , css "height" "100vh" 210 | , css "align-items" "center" 211 | , css "justify-content" "center" 212 | ] 213 | [ Loading.indeterminate ] 214 | -------------------------------------------------------------------------------- /src/Pages/About/About.elm: -------------------------------------------------------------------------------- 1 | module Pages.About.About exposing (..) 2 | 3 | import Html exposing (Html, text, div, span, p, a) 4 | import Html.Attributes exposing (href) 5 | import Material 6 | import Material.Grid as Grid exposing (grid, size, cell, Device(..)) 7 | import Material.Elevation as Elevation 8 | import Material.Color as Color 9 | import Material.Button as Button 10 | import Material.Options as Options exposing (when, css, cs, Style, onClick) 11 | import Material.Typography as Typo 12 | import Material.Table as Table 13 | import Material.Dialog as Dialog 14 | import Material.Menu as Menu 15 | import Markdown 16 | import Types exposing (..) 17 | 18 | 19 | view : Taco -> Html msg 20 | view taco = 21 | grid [ Options.id "top", Options.css "max-width" "1280px" ] 22 | [ cell 23 | [ size All 12 24 | , Elevation.e2 25 | , Options.css "padding" "6px 4px" 26 | , Options.css "display" "flex" 27 | , Options.css "flex-direction" "column" 28 | , Options.css "align-items" "left" 29 | ] 30 | [ Markdown.toHtml [] introText 31 | ] 32 | ] 33 | 34 | 35 | introText = 36 | """\x0D 37 | ### About\x0D 38 | This is an attempt to provide a link and comparision between similar concepts and operations and their usage between different functional programming languages . When learning and working with different languages and concepts, it's nice to have an easy way of looking up the implementations. Please contribute! I am not an expert in these languages. Please contribute to improvements with PR's and issues to help improve this reference.\x0D 39 | \x0D 40 | #### Roadmap\x0D 41 | * More languages\x0D 42 | * More concepts\x0D 43 | * Searching\x0D 44 | * Improve layout/colors\x0D 45 | * Improve deployment/webpack setup\x0D 46 | * Other suggestions / improvements\x0D 47 | \x0D 48 | #### Contributing\x0D 49 | * [Check out contribution guidelines here for:](https://github.com/hakonrossebo/functional-programming-babelfish/blob/master/CONTRIBUTE.md)\x0D 50 | * Ways to contribute\x0D 51 | * Structure of json files\x0D 52 | * Running without Elm installed\x0D 53 | * Running with Elm installed\x0D 54 | \x0D 55 | #### Other sites with related content\x0D 56 | [https://github.com/hemanth/functional-programming-jargon](https://github.com/hemanth/functional-programming-jargon)\x0D 57 | """ 58 | 59 | 60 | showText : (List (Html.Attribute m) -> List (Html msg) -> a) -> Options.Property c m -> String -> a 61 | showText elementType displayStyle text_ = 62 | Options.styled elementType [ displayStyle, Typo.left ] [ text text_ ] 63 | -------------------------------------------------------------------------------- /src/Pages/Babelfish/Babelfish.elm: -------------------------------------------------------------------------------- 1 | module Pages.Babelfish.Babelfish exposing (..) 2 | 3 | import Html exposing (Html, text, div, span, p, a) 4 | import Material 5 | import Material.Grid as Grid exposing (grid, size, cell, Device(..)) 6 | import Material.Elevation as Elevation 7 | import Material.Color as Color 8 | import Material.Options as Options exposing (when, css, cs, Style, onClick) 9 | import Material.Typography as Typo 10 | import Material.Menu as Menu 11 | import RemoteData exposing (WebData, RemoteData(..)) 12 | import Types exposing (..) 13 | import Decoders exposing (..) 14 | import Http exposing (Error) 15 | import Pages.Babelfish.Messages exposing (..) 16 | import Pages.Babelfish.ViewConceptMatrix as ViewConceptMatrix exposing (ConceptLanguagesViewModel(..)) 17 | import Pages.Babelfish.ViewFullConcepts as ViewFullConcepts 18 | import Pages.Babelfish.Helpers exposing (..) 19 | import CustomPorts exposing (..) 20 | 21 | type alias Model = 22 | { mdl : Material.Model 23 | , concepts : WebData (List Concept) 24 | , displayLanguages : List String 25 | , conceptLanguagesViewModel : ConceptLanguagesViewModel 26 | } 27 | 28 | subs : Model -> Sub Msg 29 | subs model = 30 | Menu.subs Mdl model.mdl 31 | 32 | 33 | init : Taco -> ( Model, Cmd Msg ) 34 | init taco = 35 | let 36 | languages = 37 | List.take 4 taco.availableLanguages 38 | |> List.map (\language -> language.name) 39 | in 40 | ( { mdl = Material.model 41 | , concepts = RemoteData.NotAsked 42 | , displayLanguages = languages 43 | , conceptLanguagesViewModel = NotCreated 44 | } 45 | , fetchData 46 | ) 47 | 48 | 49 | fetchData : Cmd Msg 50 | fetchData = 51 | Cmd.batch 52 | [ fetchConcepts 53 | ] 54 | 55 | 56 | fetchConcepts : Cmd Msg 57 | fetchConcepts = 58 | Http.get "concepts.json" decodeConcepts 59 | |> RemoteData.sendRequest 60 | |> Cmd.map ConceptsResponse 61 | 62 | 63 | update : Msg -> Model -> ( Model, Cmd Msg, SharedMsg ) 64 | update msg model = 65 | case msg of 66 | Mdl msg_ -> 67 | let 68 | ( model_, cmd_ ) = 69 | Material.update Mdl msg_ model 70 | in 71 | ( model_, cmd_, NoSharedMsg ) 72 | 73 | ScrollToDomId id -> 74 | ( model, scrollIdIntoView id, NoSharedMsg ) 75 | 76 | ConceptsResponse response -> 77 | ( { model | concepts = response, conceptLanguagesViewModel = ViewConceptMatrix.createConceptLanguagesViewModel model.displayLanguages response }, Cmd.none, NoSharedMsg ) 78 | 79 | SelectLanguage currentLanguage language -> 80 | let 81 | displayLanguages = 82 | updateDisplayLanguages currentLanguage language model.displayLanguages 83 | 84 | conceptLanguagesViewModel = 85 | ViewConceptMatrix.createConceptLanguagesViewModel displayLanguages model.concepts 86 | in 87 | ( { model | displayLanguages = displayLanguages, conceptLanguagesViewModel = conceptLanguagesViewModel }, Cmd.none, NoSharedMsg ) 88 | 89 | 90 | updateDisplayLanguages : String -> String -> List String -> List String 91 | updateDisplayLanguages currentLanguage newLanguage displayLanguages = 92 | displayLanguages 93 | |> List.map 94 | (\language -> 95 | if currentLanguage == language then 96 | newLanguage 97 | else 98 | language 99 | ) 100 | 101 | 102 | 103 | view : Taco -> Model -> Html Msg 104 | view taco model = 105 | grid [ Options.id "top", css "max-width" "1280px" ] 106 | [ cell 107 | [ size All 12 108 | , Elevation.e2 109 | , css "padding" "6px 4px" 110 | , css "display" "flex" 111 | , css "flex-direction" "column" 112 | , css "align-items" "left" 113 | ] 114 | [ showText div Typo.body1 "This is an attempt to provide a link and comparision between similar concepts and operations and their usage between different functional programming languages . When learning and working with different languages and concepts, it's nice to have an easy way of looking up the implementations. Please contribute! I am not an expert in these languages. Please contribute to improvements with PR's and issues to help improve this reference." 115 | , showText div Typo.body1 "The table is limited to showing 4 languages simultaneously. When there are more languages available, you can choose other languages in the table header menus." 116 | , viewConceptsMatrix taco model 117 | ] 118 | , cell 119 | [ size All 12 120 | , Elevation.e2 121 | , css "padding" "6px 4px" 122 | , css "display" "flex" 123 | , css "flex-direction" "column" 124 | , css "align-items" "left" 125 | ] 126 | [ showText div Typo.display1 "Concept details" 127 | , viewFullConcepts taco model 128 | ] 129 | ] 130 | 131 | 132 | white : Options.Property a b 133 | white = 134 | Color.text Color.white 135 | 136 | 137 | viewConceptsMatrix : Taco -> Model -> Html Msg 138 | viewConceptsMatrix taco model = 139 | case model.conceptLanguagesViewModel of 140 | NotCreated -> 141 | text "Initialising." 142 | 143 | Created header rows -> 144 | ViewConceptMatrix.viewConceptsMatrixSuccess taco model.displayLanguages model.mdl header rows 145 | 146 | 147 | 148 | viewFullConcepts : Taco -> Model -> Html Msg 149 | viewFullConcepts taco model = 150 | case model.concepts of 151 | NotAsked -> 152 | text "Initialising." 153 | 154 | Loading -> 155 | text "Loading." 156 | 157 | Failure err -> 158 | text ("Error: " ++ toString err) 159 | 160 | Success data -> 161 | ViewFullConcepts.viewFullConceptSuccess taco model.mdl data 162 | -------------------------------------------------------------------------------- /src/Pages/Babelfish/Helpers.elm: -------------------------------------------------------------------------------- 1 | module Pages.Babelfish.Helpers exposing (..) 2 | 3 | import Material.Typography as Typo 4 | import Material.Options as Options exposing (when, css, cs, Style, onClick) 5 | import Html exposing (Html, text, div, span, p, a) 6 | import Regex 7 | 8 | createConceptNameId : String -> String 9 | createConceptNameId name = 10 | name 11 | |> Regex.replace Regex.All (Regex.regex "[ ]") (\_ -> "_") 12 | 13 | showText : (List (Html.Attribute m) -> List (Html msg) -> a) -> Options.Property c m -> String -> a 14 | showText elementType displayStyle text_ = 15 | Options.styled elementType [ displayStyle, Typo.left ] [ text text_ ] 16 | -------------------------------------------------------------------------------- /src/Pages/Babelfish/Messages.elm: -------------------------------------------------------------------------------- 1 | module Pages.Babelfish.Messages exposing (..) 2 | 3 | import Material 4 | import RemoteData exposing (WebData, RemoteData(..)) 5 | import Types exposing (..) 6 | 7 | type Msg 8 | = Mdl (Material.Msg Msg) 9 | | ConceptsResponse (WebData (List Concept)) 10 | | SelectLanguage String String 11 | | ScrollToDomId String 12 | -------------------------------------------------------------------------------- /src/Pages/Babelfish/ViewConceptMatrix.elm: -------------------------------------------------------------------------------- 1 | module Pages.Babelfish.ViewConceptMatrix exposing (..) 2 | 3 | import Html exposing (Html, text, div, span, p, a) 4 | import Material 5 | import Material.Menu as Menu 6 | import Material.Button as Button 7 | import Material.Options as Options exposing (when, css, cs, Style, onClick) 8 | import RemoteData exposing (WebData, RemoteData(..)) 9 | import Material.Table as Table 10 | import Material.Icon as Icon 11 | import Material.Tooltip as Tooltip 12 | import Material.Typography as Typo 13 | import Types exposing (Concept, LanguageImplementation, Taco) 14 | import Pages.Babelfish.Helpers exposing (..) 15 | import Pages.Babelfish.Messages exposing (..) 16 | import Pages.Babelfish.Helpers exposing (..) 17 | 18 | type alias RowLanguageImplementations = 19 | List String 20 | 21 | 22 | type ConceptLanguagesViewModel 23 | = NotCreated 24 | | Created RowLanguageImplementations (List ( RowLanguageImplementations, RowLanguageImplementations )) 25 | 26 | createConceptLanguagesViewModel : List String -> WebData (List Concept) -> ConceptLanguagesViewModel 27 | createConceptLanguagesViewModel displayLanguages concepts = 28 | case concepts of 29 | Success data -> 30 | let 31 | header = 32 | displayLanguages 33 | 34 | rows = 35 | data 36 | |> List.map (\concept -> createConceptLanguagesViewModelRow displayLanguages concept.languageImplementations concept.name concept.description) 37 | in 38 | Created header rows 39 | 40 | _ -> 41 | NotCreated 42 | 43 | 44 | createConceptLanguagesViewModelRow : List String -> List LanguageImplementation -> String -> String -> ( RowLanguageImplementations, RowLanguageImplementations ) 45 | createConceptLanguagesViewModelRow displayLanguages languageImplementations name desc = 46 | let 47 | languages = 48 | displayLanguages 49 | |> List.map (\lang -> findLanguageImplementation lang languageImplementations) 50 | in 51 | ( [ name, desc ], languages ) 52 | 53 | 54 | findLanguageImplementation : String -> List LanguageImplementation -> String 55 | findLanguageImplementation lang languageImplementations = 56 | languageImplementations 57 | |> List.filter (\x -> x.name == lang) 58 | |> List.map (\x -> x.code) 59 | |> List.head 60 | |> Maybe.withDefault "" 61 | 62 | 63 | 64 | viewConceptsMatrixSuccess : Taco -> List String -> Material.Model -> RowLanguageImplementations -> List ( RowLanguageImplementations, RowLanguageImplementations ) -> Html Msg 65 | viewConceptsMatrixSuccess taco displayLanguages outerMdl header rows = 66 | let 67 | descriptions = 68 | [ Table.th 69 | [ css "width" "30%" 70 | , css "vertical-align" "middle" 71 | ] 72 | [ showText div Typo.body2 "Concept" 73 | ] 74 | , Table.th 75 | [ css "width" "10%" 76 | , css "vertical-align" "middle" 77 | ] 78 | [ showText div Typo.body2 "Name" 79 | ] 80 | ] 81 | 82 | availableWidth = 83 | 60 84 | 85 | languageColumnSize = 86 | displayLanguages 87 | |> List.length 88 | |> (//) availableWidth 89 | |> toString 90 | 91 | languageNames = 92 | displayLanguages 93 | |> List.indexedMap (\idx lang -> viewConceptLanguageHeader idx taco displayLanguages outerMdl languageColumnSize lang) 94 | in 95 | Table.table [ css "table-layout" "fixed", css "width" "100%" ] 96 | [ Table.thead 97 | [] 98 | [ Table.tr [] (List.append descriptions languageNames) 99 | ] 100 | , Table.tbody [] 101 | (rows 102 | |> List.indexedMap (\idx item -> viewConceptItem idx item outerMdl) 103 | ) 104 | ] 105 | 106 | 107 | viewConceptLanguageHeader : Int -> Taco -> List String -> Material.Model -> String -> String -> Html Msg 108 | viewConceptLanguageHeader index taco displayLanguages outerMdl size name = 109 | Table.th 110 | [ css "text-align" "left" 111 | , css "align-items" "center" 112 | ] 113 | [ Options.styled span [ Typo.body2, Typo.left, Typo.justify ] [ text name ] 114 | , viewLanguageSelectMenu index taco displayLanguages outerMdl name 115 | ] 116 | 117 | 118 | viewLanguageSelectMenu : Int -> Taco -> List String -> Material.Model -> String -> Html Msg 119 | viewLanguageSelectMenu index taco displayLanguages outerMdl language = 120 | Menu.render Mdl 121 | [ index ] 122 | outerMdl 123 | [ css "float" "right" 124 | , Menu.ripple 125 | , Menu.bottomLeft 126 | , Menu.icon "keyboard_arrow_down" 127 | ] 128 | (getMenuItems language taco displayLanguages) 129 | 130 | 131 | getMenuItems : String -> Taco -> List String -> List (Menu.Item Msg) 132 | getMenuItems currentLanguage taco displayLanguages = 133 | taco.availableLanguages 134 | |> List.filter (\availableLanguage -> not (List.any (\language -> language == availableLanguage.name) displayLanguages)) 135 | |> List.map (\language -> viewMenuItem currentLanguage language.name) 136 | 137 | 138 | viewMenuItem : String -> String -> Menu.Item Msg 139 | viewMenuItem currentLanguage newLanguage = 140 | Menu.item 141 | [ Menu.onSelect (SelectLanguage currentLanguage newLanguage) ] 142 | [ text newLanguage ] 143 | 144 | 145 | 146 | viewConceptItem : Int -> ( RowLanguageImplementations, RowLanguageImplementations ) -> Material.Model -> Html Msg 147 | viewConceptItem idx ( descRow, codeRow ) outerMdl = 148 | let 149 | code = 150 | codeRow 151 | |> List.map (\row -> viewConceptLanguage row) 152 | 153 | desc = 154 | descRow 155 | |> List.indexedMap (\idx row -> viewConceptLanguageDescription idx outerMdl row) 156 | in 157 | List.append desc code 158 | |> Table.tr [] 159 | 160 | 161 | viewConceptLanguageDescription : Int -> Material.Model -> String -> Html Msg 162 | viewConceptLanguageDescription idx outerMdl descriptionText = 163 | let 164 | content = 165 | if idx == 0 then 166 | [ Button.render Mdl 167 | [ 1, idx ] 168 | outerMdl 169 | [ Button.icon 170 | , Options.onClick (ScrollToDomId <| createConceptNameId descriptionText) 171 | ] 172 | [ Icon.view "zoom_in" [ Tooltip.attach Mdl [ 1, idx ] ], Tooltip.render Mdl [ 1, idx ] outerMdl [] [ text "Go to details" ] ] 173 | , text descriptionText 174 | ] 175 | else 176 | [ text descriptionText ] 177 | in 178 | Table.td [ css "text-align" "left", css "background-color" "#f6f6f6", cs "wrapword" ] (content) 179 | 180 | 181 | viewConceptLanguage : String -> Html Msg 182 | viewConceptLanguage code = 183 | Table.td [ css "text-align" "left", cs "wrapword" ] [ text code ] 184 | -------------------------------------------------------------------------------- /src/Pages/Babelfish/ViewFullConcepts.elm: -------------------------------------------------------------------------------- 1 | module Pages.Babelfish.ViewFullConcepts exposing (..) 2 | 3 | import Html exposing (Html, text, div, span, p, a) 4 | import Html.Attributes exposing (href) 5 | import Material 6 | import Material.Button as Button 7 | import Material.Options as Options exposing (when, css, cs, Style, onClick) 8 | import Material.Elevation as Elevation 9 | import Material.Table as Table 10 | import Material.Icon as Icon 11 | import Material.Tooltip as Tooltip 12 | import Material.Typography as Typo 13 | import Material.Grid as Grid exposing (grid, size, cell, Device(..)) 14 | import Types exposing (Concept, LanguageImplementation, Taco, ConceptLink, Language) 15 | import Markdown 16 | import Pages.Babelfish.Helpers exposing (..) 17 | import Pages.Babelfish.Messages exposing (..) 18 | import Pages.Babelfish.Helpers exposing (..) 19 | 20 | 21 | viewFullConceptSuccess : Taco -> Material.Model -> List Concept -> Html Msg 22 | viewFullConceptSuccess taco outerMdl data = 23 | data 24 | |> List.indexedMap (\idx item -> viewFullConcept idx taco outerMdl item) 25 | |> div [] 26 | 27 | 28 | viewFullConcept : Int -> Taco -> Material.Model -> Concept -> Html Msg 29 | viewFullConcept idx taco outerMdl concept = 30 | grid [ Options.id <| createConceptNameId concept.name, css "max-width" "1280px" ] 31 | [ cell 32 | [ size All 12 33 | , css "padding" "6px 4px" 34 | , css "display" "flex" 35 | , css "flex-direction" "row" 36 | , css "align-items" "left" 37 | ] 38 | [ Button.render Mdl 39 | [ 0, idx ] 40 | outerMdl 41 | [ Button.icon 42 | , Options.onClick (ScrollToDomId "top") 43 | ] 44 | [ Icon.view "arrow_upward" [ Tooltip.attach Mdl [ 0, idx ] ], Tooltip.render Mdl [ 0, idx ] outerMdl [] [ text "Back to top" ] ] 45 | , showText span Typo.headline concept.name 46 | ] 47 | , cell 48 | [ size All 12 49 | , css "padding" "6px 4px" 50 | , css "display" "flex" 51 | , css "flex-direction" "column" 52 | , css "align-items" "left" 53 | ] 54 | [ viewConceptLanguageCodeTable concept.languageImplementations 55 | ] 56 | , cell 57 | [ size All 12 58 | -- , Elevation.e2 59 | , css "padding" "6px 4px" 60 | , css "display" "flex" 61 | , css "flex-direction" "row" 62 | , css "align-items" "stretch" 63 | , css "justify-content" "flex-start" 64 | , css "align-content" "stretch" 65 | ] 66 | [ viewConceptNote concept.notes 67 | , viewConceptLinks concept.links 68 | ] 69 | , cell 70 | [ size All 12 71 | , css "padding" "6px 4px" 72 | , css "display" "flex" 73 | , css "flex-direction" "column" 74 | , css "align-items" "left" 75 | ] 76 | [ viewConceptLanguageExamples taco concept.languageImplementations 77 | ] 78 | ] 79 | 80 | viewConceptNote : Maybe String -> Html Msg 81 | viewConceptNote note = 82 | case note of 83 | Just note_ -> 84 | Options.div 85 | [ Elevation.e2 86 | , css "height" "196px" 87 | , css "flex" "1 0 auto" 88 | , css "overflow" "auto" 89 | , css "border-radius" "2px" 90 | , css "width" "500px" 91 | , css "margin-right" "1rem" 92 | , css "padding" "16px 16px 16px 16px" 93 | ] 94 | [ showText div Typo.caption "Notes" 95 | , text note_ 96 | ] 97 | 98 | Nothing -> 99 | text "" 100 | 101 | 102 | viewConceptLinks : List ConceptLink -> Html Msg 103 | viewConceptLinks links = 104 | Options.div 105 | [ Elevation.e2 106 | , css "height" "196px" 107 | , css "flex" "1 0 auto" 108 | , css "overflow" "auto" 109 | , css "border-radius" "2px" 110 | , css "width" "500px" 111 | , css "margin-left" "1rem" 112 | , css "padding" "16px 16px 16px 16px" 113 | ] 114 | [ showText div Typo.caption "Links" 115 | , div [] 116 | (links 117 | |> List.map (\link -> div [] [ a [ href link.url, Html.Attributes.target "_blank" ] [ text link.description ] ]) 118 | ) 119 | ] 120 | 121 | 122 | viewConceptLanguageCodeTable : List LanguageImplementation -> Html Msg 123 | viewConceptLanguageCodeTable languages = 124 | Table.table [ css "table-layout" "fixed", css "width" "100%" ] 125 | [ Table.thead 126 | [] 127 | [ Table.tr [] 128 | [ Table.th 129 | [ css "width" "30%" ] 130 | [ showText div Typo.body2 "Language" 131 | ] 132 | , Table.th [ css "width" "70%" ] 133 | [ showText div Typo.body2 "Code" 134 | ] 135 | ] 136 | ] 137 | , Table.tbody [] 138 | (languages 139 | |> List.indexedMap (\idx item -> viewConceptLanguageCodeTableItem idx item) 140 | ) 141 | ] 142 | 143 | 144 | viewConceptLanguageCodeTableItem : Int -> LanguageImplementation -> Html Msg 145 | viewConceptLanguageCodeTableItem index language = 146 | Table.tr 147 | [] 148 | [ Table.td [ css "text-align" "left" ] [ text language.name ] 149 | , Table.td [ css "text-align" "left" ] [ text language.code ] 150 | ] 151 | 152 | 153 | viewConceptLanguageExamples : Taco -> List LanguageImplementation -> Html Msg 154 | viewConceptLanguageExamples taco languages = 155 | Options.div 156 | [ Elevation.e2 157 | -- , css "height" "196px" 158 | , css "flex" "1 1 auto" 159 | , css "overflow" "auto" 160 | , css "border-radius" "2px" 161 | , css "width" "97%" 162 | , css "margin-top" "1rem" 163 | , css "padding" "16px 16px 16px 16px" 164 | ] 165 | [ showText div Typo.caption "Examples" 166 | , div [] 167 | (languages 168 | |> List.map (\language -> viewLanguageConceptExample taco.availableLanguages language) 169 | ) 170 | ] 171 | 172 | 173 | viewLanguageConceptExample : List Language -> LanguageImplementation -> Html Msg 174 | viewLanguageConceptExample availableLanguages language = 175 | case language.example of 176 | Just example -> 177 | let 178 | languageHighlightCodeName = 179 | availableLanguages 180 | |> List.filter (\lang -> lang.name == language.name) 181 | |> List.map (\lang -> lang.languageCode) 182 | |> List.head 183 | |> Maybe.withDefault "haskell" 184 | in 185 | viewLanguageConceptExampleContainer language.name languageHighlightCodeName example 186 | 187 | Nothing -> 188 | text "" 189 | 190 | 191 | viewLanguageConceptExampleContainer : String -> String -> List String -> Html Msg 192 | viewLanguageConceptExampleContainer name hightlightCodeName insideHtml = 193 | let 194 | combinedExample = 195 | insideHtml 196 | |> List.foldr (\first next -> String.append first (String.append "\n" next) ) "" 197 | in 198 | Options.div 199 | [ --Elevation.e2 200 | -- , css "height" "196px" 201 | css "flex" "1 1 auto" 202 | , css "overflow" "auto" 203 | , css "border-radius" "2px" 204 | -- , css "width" "528px" 205 | -- , css "margin-top" "4rem" 206 | , css "padding" "16px 16px 16px 16px" 207 | ] 208 | [ showText div Typo.caption name 209 | , viewFormattedLanguageExample hightlightCodeName [] combinedExample 210 | ] 211 | 212 | 213 | viewFormattedLanguageExample : String -> List (Options.Property c m) -> String -> Html m 214 | viewFormattedLanguageExample language options str = 215 | Options.styled 216 | (Markdown.toHtmlWith Markdown.defaultOptions) 217 | (Options.many 218 | [ css "overflow" "auto" 219 | , css "flex" "1 1 auto" 220 | -- , css "border-radius" "2px" 221 | -- , css "font-size" "10pt" 222 | -- , Color.background (Color.color Color.BlueGrey Color.S50) 223 | , css "background" "#002b36" 224 | -- , css "background" "#23241f" 225 | , css "color" "#fefefe" 226 | , css "padding" "6px 6px 6px 6px" 227 | -- , Elevation.e2 228 | ] 229 | :: options 230 | ) 231 | ("```" ++ language ++ "\n" ++ str ++ "\n```") 232 | -------------------------------------------------------------------------------- /src/Routing/Helpers.elm: -------------------------------------------------------------------------------- 1 | module Routing.Helpers exposing (..) 2 | 3 | import Navigation exposing (Location) 4 | import UrlParser as Url exposing (()) 5 | import Types exposing (..) 6 | 7 | 8 | reverseRoute : Route -> String 9 | reverseRoute route = 10 | case route of 11 | RouteAbout -> 12 | "#/about" 13 | 14 | RouteBabelfish -> 15 | "#/" 16 | 17 | _ -> 18 | "#/" 19 | 20 | 21 | routeParser : Url.Parser (Route -> a) a 22 | routeParser = 23 | Url.oneOf 24 | [ Url.map RouteBabelfish Url.top 25 | , Url.map RouteAbout (Url.s "about") 26 | , Url.map RouteBabelfish (Url.s "#/") 27 | ] 28 | 29 | 30 | parseLocation : Location -> Route 31 | parseLocation location = 32 | location 33 | |> Url.parseHash routeParser 34 | |> Maybe.withDefault NotFoundRoute 35 | 36 | 37 | fromTabToRoute : Int -> Route 38 | fromTabToRoute tabIndex = 39 | case tabIndex of 40 | 0 -> 41 | RouteBabelfish 42 | 43 | 1 -> 44 | RouteAbout 45 | 46 | _ -> 47 | RouteBabelfish 48 | 49 | 50 | fromRouteToTab : Route -> Int 51 | fromRouteToTab route = 52 | case route of 53 | RouteBabelfish -> 54 | 0 55 | 56 | RouteAbout -> 57 | 1 58 | 59 | _ -> 60 | 0 61 | -------------------------------------------------------------------------------- /src/Routing/Router.elm: -------------------------------------------------------------------------------- 1 | module Routing.Router exposing (..) 2 | 3 | import Material.Snackbar as Snackbar 4 | import Navigation exposing (Location) 5 | import Html exposing (..) 6 | import Html.Attributes exposing (href) 7 | import Types exposing (Route(..), TacoUpdate(..), Taco, SharedMsg(..)) 8 | import Routing.Helpers exposing (parseLocation, reverseRoute, fromTabToRoute) 9 | import Pages.Babelfish.Messages as BabelfishMessages 10 | import Pages.Babelfish.Babelfish as Babelfish 11 | import Pages.About.About as About 12 | import Material 13 | import Material.Layout as Layout 14 | import Material.Snackbar as Snackbar 15 | import Material.Icon as Icon 16 | import Material.Color as Color 17 | import Material.Dialog as Dialog 18 | import Material.Button as Button 19 | import Material.Options as Options exposing (css, cs, when) 20 | 21 | 22 | styles : String 23 | styles = 24 | """\x0D\x0D 25 | .demo-options .mdl-checkbox__box-outline {\x0D\x0D 26 | border-color: rgba(255, 255, 255, 0.89);\x0D\x0D 27 | }\x0D\x0D 28 | \x0D\x0D 29 | .mdl-layout__drawer {\x0D\x0D 30 | border: none !important;\x0D\x0D 31 | }\x0D\x0D 32 | \x0D\x0D 33 | .mdl-layout__drawer .mdl-navigation__link:hover {\x0D\x0D 34 | background-color: #00BCD4 !important;\x0D\x0D 35 | color: #37474F !important;\x0D\x0D 36 | }\x0D\x0D 37 | """ 38 | 39 | 40 | type alias Model = 41 | { mdl : Material.Model 42 | , selectedTab : Int 43 | , snackbar : Snackbar.Model (Maybe Msg) 44 | , route : Route 45 | , babelfishModel : Babelfish.Model 46 | } 47 | 48 | 49 | type Msg 50 | = Mdl (Material.Msg Msg) 51 | | Snackbar (Snackbar.Msg (Maybe Msg)) 52 | | UrlChange Location 53 | | SelectTab Int 54 | | NavigateTo Route 55 | | BabelfishMsg BabelfishMessages.Msg 56 | 57 | 58 | subs : Model -> Sub Msg 59 | subs model = 60 | case model.route of 61 | RouteBabelfish -> 62 | Sub.map BabelfishMsg (Babelfish.subs model.babelfishModel) 63 | 64 | RouteAbout -> 65 | Sub.none 66 | 67 | NotFoundRoute -> 68 | Sub.none 69 | 70 | 71 | init : Location -> Taco -> ( Model, Cmd Msg ) 72 | init location taco = 73 | let 74 | ( babelfishModel, babelfishCmd ) = 75 | Babelfish.init taco 76 | in 77 | ( { mdl = Material.model 78 | , selectedTab = 0 79 | , snackbar = Snackbar.model 80 | , babelfishModel = babelfishModel 81 | , route = parseLocation location 82 | } 83 | , Cmd.batch [ Cmd.map BabelfishMsg babelfishCmd ] 84 | ) 85 | 86 | 87 | update : Msg -> Model -> ( Model, Cmd Msg, TacoUpdate ) 88 | update msg model = 89 | case msg of 90 | Mdl msg_ -> 91 | let 92 | ( mdlModel, mdlCmd ) = 93 | Material.update Mdl msg_ model 94 | in 95 | ( mdlModel, mdlCmd, NoUpdate ) 96 | 97 | SelectTab k -> 98 | ( { model | selectedTab = k }, calculateNavigateUrlMessage k, NoUpdate ) 99 | 100 | Snackbar msg_ -> 101 | let 102 | ( snackbar, snackCmd ) = 103 | Snackbar.update msg_ model.snackbar 104 | in 105 | ( { model | snackbar = snackbar }, Cmd.map Snackbar snackCmd, NoUpdate ) 106 | 107 | UrlChange location -> 108 | let 109 | ( snackModel, snackCmd ) = 110 | Snackbar.add (Snackbar.toast Nothing "Url changed") model.snackbar 111 | in 112 | ( { model | route = parseLocation location, snackbar = snackModel } 113 | , Cmd.batch 114 | [ Cmd.map Snackbar snackCmd 115 | ] 116 | , NoUpdate 117 | ) 118 | 119 | NavigateTo route -> 120 | ( model 121 | , Navigation.newUrl (reverseRoute route) 122 | , NoUpdate 123 | ) 124 | 125 | BabelfishMsg babelfishMsg -> 126 | updateBabelfish model babelfishMsg 127 | 128 | 129 | calculateNavigateUrlMessage : Int -> Cmd Msg 130 | calculateNavigateUrlMessage tabIndex = 131 | fromTabToRoute tabIndex 132 | |> reverseRoute 133 | |> Navigation.newUrl 134 | 135 | 136 | updateBabelfish : Model -> BabelfishMessages.Msg -> ( Model, Cmd Msg, TacoUpdate ) 137 | updateBabelfish model babelfishMsg = 138 | let 139 | ( nextBabelfishModel, babelfishCmd, sharedMsg ) = 140 | Babelfish.update babelfishMsg model.babelfishModel 141 | in 142 | ( { model | babelfishModel = nextBabelfishModel } 143 | , Cmd.map BabelfishMsg babelfishCmd 144 | , NoUpdate 145 | ) 146 | |> addSharedMsgToUpdate sharedMsg 147 | 148 | 149 | addSharedMsgToUpdate : SharedMsg -> ( Model, Cmd Msg, TacoUpdate ) -> ( Model, Cmd Msg, TacoUpdate ) 150 | addSharedMsgToUpdate sharedMsg ( model, msg, tacoUpdate ) = 151 | case sharedMsg of 152 | CreateSnackbarToast toastMessage -> 153 | let 154 | ( snackModel, snackCmd ) = 155 | Snackbar.add (Snackbar.toast Nothing toastMessage) model.snackbar 156 | in 157 | ( { model | snackbar = snackModel } 158 | , Cmd.batch 159 | [ Cmd.map Snackbar snackCmd 160 | , msg 161 | ] 162 | , tacoUpdate 163 | ) 164 | 165 | NoSharedMsg -> 166 | ( model, msg, tacoUpdate ) 167 | 168 | 169 | view : Taco -> Model -> Html Msg 170 | view taco model = 171 | div [] <| 172 | [ Options.stylesheet styles 173 | , Layout.render Mdl 174 | model.mdl 175 | [ Layout.selectedTab model.selectedTab 176 | , Layout.onSelectTab SelectTab 177 | , Layout.fixedHeader 178 | -- , Layout.fixedDrawer 179 | -- , Layout.fixedTabs 180 | , Options.css "display" "flex !important" 181 | , Options.css "flex-direction" "row" 182 | , Options.css "align-items" "center" 183 | ] 184 | { header = [ viewHeader taco model ] 185 | , drawer = 186 | [ drawerHeader model, viewDrawer model ] 187 | -- , tabs = ( tabTitles, [] ) 188 | , tabs = ( [], [] ) 189 | , main = 190 | [ pageView taco model 191 | , Snackbar.view model.snackbar |> map Snackbar 192 | ] 193 | } 194 | , helpDialog model 195 | ] 196 | 197 | 198 | viewHeader : Taco -> Model -> Html Msg 199 | viewHeader taco model = 200 | Layout.row 201 | [ Color.background <| Color.color Color.Grey Color.S100 202 | , Color.text <| Color.color Color.Grey Color.S900 203 | ] 204 | [ Layout.title [] [ text "Functional programming babelfish" ] 205 | , Layout.spacer 206 | , Layout.navigation [] 207 | [ Layout.link 208 | [ Layout.href "https://github.com/hakonrossebo/functional-programming-babelfish" ] 209 | [ span [] [ text "Fork me on Github" ] ] 210 | ] 211 | ] 212 | 213 | 214 | type alias MenuItem = 215 | { text : String 216 | , iconName : String 217 | , route : Types.Route 218 | } 219 | 220 | 221 | 222 | --todo-refactor 223 | 224 | 225 | tabTitles : List (Html Msg) 226 | tabTitles = 227 | [ text "Cheat sheet", text "About" ] 228 | 229 | 230 | menuItems : List MenuItem 231 | menuItems = 232 | [ { text = "Cheat sheet", iconName = "dashboard", route = RouteBabelfish } 233 | , { text = "About", iconName = "dashboard", route = RouteAbout } 234 | ] 235 | 236 | 237 | viewDrawerMenuItem : Model -> MenuItem -> Html Msg 238 | viewDrawerMenuItem model menuItem = 239 | Layout.link 240 | [ Options.onClick (NavigateTo menuItem.route) 241 | , when ((model.route) == menuItem.route) (Color.background <| Color.color Color.BlueGrey Color.S600) 242 | , Options.css "color" "rgba(255, 255, 255, 0.56)" 243 | , Options.css "font-weight" "500" 244 | ] 245 | [ Icon.view menuItem.iconName 246 | [ Color.text <| Color.color Color.BlueGrey Color.S500 247 | , Options.css "margin-right" "32px" 248 | ] 249 | , text menuItem.text 250 | ] 251 | 252 | 253 | viewDrawer : Model -> Html Msg 254 | viewDrawer model = 255 | Layout.navigation 256 | [ Color.background <| Color.color Color.BlueGrey Color.S800 257 | , Color.text <| Color.color Color.BlueGrey Color.S50 258 | , Options.css "flex-grow" "1" 259 | ] 260 | <| 261 | (List.map (viewDrawerMenuItem model) menuItems) 262 | 263 | 264 | drawerHeader : Model -> Html Msg 265 | drawerHeader model = 266 | Options.styled Html.header 267 | [ css "display" "flex" 268 | , css "box-sizing" "border-box" 269 | , css "justify-content" "flex-end" 270 | , css "padding" "16px" 271 | , css "height" "151px" 272 | , css "flex-direction" "column" 273 | , cs "demo-header" 274 | , Color.background <| Color.color Color.BlueGrey Color.S900 275 | , Color.text <| Color.color Color.BlueGrey Color.S50 276 | ] 277 | [ Options.styled Html.img 278 | [ Options.attribute <| Html.Attributes.src "images/elm.png" 279 | , css "width" "48px" 280 | , css "height" "48px" 281 | , css "border-radius" "24px" 282 | ] 283 | [] 284 | , Options.styled Html.div 285 | [ css "display" "flex" 286 | , css "flex-direction" "row" 287 | , css "align-items" "center" 288 | , css "width" "100%" 289 | , css "position" "relative" 290 | ] 291 | [ Layout.spacer 292 | ] 293 | ] 294 | 295 | 296 | pageView : Taco -> Model -> Html Msg 297 | pageView taco model = 298 | case model.route of 299 | RouteBabelfish -> 300 | Babelfish.view taco model.babelfishModel 301 | |> Html.map BabelfishMsg 302 | 303 | RouteAbout -> 304 | About.view taco 305 | 306 | NotFoundRoute -> 307 | h1 [] [ text "404 :(" ] 308 | 309 | 310 | helpDialog : Model -> Html Msg 311 | helpDialog model = 312 | Dialog.view 313 | [] 314 | [ Dialog.title [] [ text "About" ] 315 | , Dialog.content [] 316 | [ Html.p [] 317 | [ text "Empty dialog" ] 318 | , Html.p [] 319 | [ text "Place text here" ] 320 | ] 321 | , Dialog.actions [] 322 | [ Options.styled Html.span 323 | [ Dialog.closeOn "click" ] 324 | [ Button.render Mdl 325 | [ 5, 1, 6 ] 326 | model.mdl 327 | [ Button.ripple 328 | ] 329 | [ text "Close" ] 330 | ] 331 | ] 332 | ] 333 | -------------------------------------------------------------------------------- /src/Types.elm: -------------------------------------------------------------------------------- 1 | module Types exposing (..) 2 | 3 | import Time exposing (Time) 4 | 5 | 6 | type alias Taco = 7 | { currentTime : Time 8 | , availableLanguages : List Language 9 | } 10 | 11 | 12 | type Route 13 | = RouteBabelfish 14 | | RouteAbout 15 | | NotFoundRoute 16 | 17 | 18 | type TacoUpdate 19 | = NoUpdate 20 | | UpdateTime Time 21 | | UpdateAvailableLanguages (List Language) 22 | 23 | 24 | type SharedMsg 25 | = CreateSnackbarToast String 26 | | NoSharedMsg 27 | 28 | 29 | type alias Language = 30 | { name : String 31 | , languageCode : String 32 | } 33 | 34 | 35 | type alias Concept = 36 | { name : String 37 | , description : String 38 | , index : Int 39 | , notes : Maybe String 40 | , languageImplementations : List LanguageImplementation 41 | , links : List ConceptLink 42 | } 43 | 44 | 45 | type alias LanguageImplementation = 46 | { name : String 47 | , code : String 48 | , example : Maybe (List String) 49 | } 50 | 51 | 52 | type alias ConceptLink = 53 | { url : String 54 | , description : String 55 | } 56 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hakonrossebo/functional-programming-babelfish/e54a5eebcc731074fa47e4e6aa932378e5a7c5dd/src/favicon.ico -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 | 11 | 12 | 19 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | require('file?name=/assets/highlight/highlight.pack.js!../assets/highlight/highlight.pack.js'); 2 | require('./main.css'); 3 | require('file?name=available-languages.json!../available-languages.json'); 4 | require('file?name=concepts.json!../concepts.json'); 5 | require('file?name=/images/elm.png!../images/elm.png'); 6 | require('file?name=/assets/highlight/solarized-dark.css!../assets/highlight/solarized-dark.css'); 7 | require('file?name=/assets/analytics.js!../assets/analytics.js'); 8 | 9 | var Elm = require('./Main.elm'); 10 | 11 | var babelFishApp = Elm.Main.embed(document.getElementById('root'), { 12 | currentTime: Date.now() 13 | }); 14 | // var babelFishApp = Elm.Main.fullscreen({ currentTime: Date.now() }); 15 | 16 | babelFishApp.ports.scrollIdIntoView.subscribe(function(domId) { 17 | document.getElementById(domId).scrollIntoView(); 18 | }); 19 | -------------------------------------------------------------------------------- /src/index_prod.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | <%= htmlWebpackPlugin.options.title %> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
21 | 22 | 23 | -------------------------------------------------------------------------------- /src/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | } 4 | 5 | #chartdiv { 6 | width : 900px; 7 | height : 400px; 8 | font-size : 11px; 9 | } 10 | .wrapword{ 11 | text-align: left !important; 12 | white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */ 13 | white-space: -webkit-pre-wrap; /*Chrome & Safari */ 14 | white-space: -pre-wrap; /* Opera 4-6 */ 15 | white-space: -o-pre-wrap; /* Opera 7 */ 16 | white-space: pre-wrap; /* css-3 */ 17 | word-wrap: break-word; /* Internet Explorer 5.5+ */ 18 | white-space: normal; 19 | } 20 | -------------------------------------------------------------------------------- /tests/Example.elm: -------------------------------------------------------------------------------- 1 | module Example exposing (..) 2 | 3 | import Test exposing (..) 4 | import Expect 5 | import Fuzz exposing (list, int, string) 6 | 7 | 8 | suite : Test 9 | suite = 10 | describe "The String module" 11 | [ describe "String.reverse" 12 | -- Nest as many descriptions as you like. 13 | [ test "has no effect on a palindrome" <| 14 | \_ -> 15 | let 16 | palindrome = 17 | "hannah" 18 | in 19 | Expect.equal palindrome (String.reverse palindrome) 20 | 21 | -- Expect.equal is designed to be used in pipeline style, like this. 22 | , test "reverses a known string" <| 23 | \_ -> 24 | "ABCDEFG" 25 | |> String.reverse 26 | |> Expect.equal "GFEDCBA" 27 | 28 | -- fuzz runs the test 100 times with randomly-generated inputs! 29 | , fuzz string "restores the original string if you run it again" <| 30 | \randomlyGeneratedString -> 31 | randomlyGeneratedString 32 | |> String.reverse 33 | |> String.reverse 34 | |> Expect.equal randomlyGeneratedString 35 | ] 36 | ] 37 | -------------------------------------------------------------------------------- /tests/elm-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0", 3 | "summary": "Test Suites", 4 | "repository": "https://github.com/hakonrossebo/functional-programming-babelfish.git", 5 | "license": "MIT", 6 | "source-directories": [ 7 | "..", 8 | "..\\src", 9 | "." 10 | ], 11 | "exposed-modules": [], 12 | "dependencies": { 13 | "elm-lang/core": "5.0.0 <= v < 6.0.0", 14 | "elm-community/elm-test": "4.0.0 <= v < 5.0.0", 15 | "debois/elm-mdl": "8.1.0 <= v < 9.0.0", 16 | "elm-lang/html": "2.0.0 <= v < 3.0.0", 17 | "elm-lang/http": "1.0.0 <= v < 2.0.0", 18 | "elm-lang/navigation": "2.0.1 <= v < 3.0.0", 19 | "elm-lang/svg": "2.0.0 <= v < 3.0.0", 20 | "evancz/elm-markdown": "3.0.1 <= v < 4.0.0", 21 | "evancz/url-parser": "2.0.1 <= v < 3.0.0", 22 | "krisajenkins/remotedata": "4.3.0 <= v < 5.0.0", 23 | "sporto/elm-dropdown": "1.2.2 <= v < 2.0.0" 24 | }, 25 | "elm-version": "0.18.0 <= v < 0.19.0" 26 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const path = require( 'path' ); 4 | 5 | const paths = { 6 | entry: path.resolve('./src/index'), 7 | dist: path.resolve('./dist'), 8 | template: path.resolve('./src/index.html'), 9 | favicon: path.resolve('./src/favicon.ico'), 10 | elmMake: path.resolve(__dirname, './node_modules/.bin/elm-make') 11 | } 12 | 13 | module.exports = { 14 | 15 | devtool: 'eval', 16 | 17 | entry: [ 18 | 'webpack-dev-server/client', 19 | paths.entry 20 | ], 21 | output: { 22 | 23 | pathinfo: true, 24 | 25 | path: paths.dist, 26 | 27 | filename: 'app', 28 | 29 | publicPath: '/' 30 | }, 31 | resolve: { 32 | extensions: ['', '.js', '.elm'] 33 | }, 34 | module: { 35 | noParse: /\.elm$/, 36 | loaders: [ 37 | { 38 | test: /\.elm$/, 39 | exclude: [ /elm-stuff/, /node_modules/ ], 40 | loader: 'elm-hot!elm-webpack?verbose=true&warn=true&debug=true&pathToMake=' + paths.elmMake 41 | }, 42 | { 43 | test: /\.css$/, 44 | exclude: [ /elm-stuff/, /node_modules/, /assets/ ], 45 | loader: "style-loader!css-loader" 46 | } 47 | ] 48 | }, 49 | plugins: [ 50 | new webpack.DefinePlugin({ 51 | API_URL: JSON.stringify('available-languages.json') 52 | }), 53 | new HtmlWebpackPlugin({ 54 | inject: true, 55 | title: "Functional programming Babelfish", 56 | template: paths.template, 57 | favicon: paths.favicon 58 | }), 59 | new webpack.HotModuleReplacementPlugin() 60 | ] 61 | }; -------------------------------------------------------------------------------- /webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const CleanWebpackPlugin = require('clean-webpack-plugin'); 4 | const path = require( 'path' ); 5 | 6 | const paths = { 7 | entry: path.resolve('./src/index'), 8 | dist: path.resolve('./docs'), 9 | template: path.resolve('./src/index_prod.html'), 10 | favicon: path.resolve('./src/favicon.ico'), 11 | elmMake: path.resolve(__dirname, './node_modules/.bin/elm-make') 12 | } 13 | 14 | module.exports = { 15 | 16 | devtool: 'eval', 17 | 18 | entry: [ 19 | paths.entry 20 | ], 21 | output: { 22 | 23 | pathinfo: true, 24 | 25 | path: paths.dist, 26 | 27 | filename: 'app-[hash]', 28 | 29 | publicPath: './' 30 | }, 31 | resolve: { 32 | extensions: ['', '.js', '.elm'] 33 | }, 34 | module: { 35 | noParse: /\.elm$/, 36 | loaders: [ 37 | { 38 | test: /\.elm$/, 39 | exclude: [ /elm-stuff/, /node_modules/ ], 40 | 41 | // Use the local installation of elm-make 42 | loader: 'elm-webpack', 43 | query: { 44 | pathToMake: paths.elmMake 45 | } 46 | }, 47 | { 48 | test: /\.css$/, 49 | exclude: [ /elm-stuff/, /node_modules/, /assets/ ], 50 | loader: "style-loader!css-loader" 51 | } 52 | ] 53 | }, 54 | plugins: [ 55 | new webpack.DefinePlugin({ 56 | API_URL: JSON.stringify('available-languages.json') 57 | }), 58 | new HtmlWebpackPlugin({ 59 | inject: true, 60 | title: "Functional programming Babelfish", 61 | template: paths.template, 62 | favicon: paths.favicon, 63 | minify: { 64 | removeComments: true, 65 | collapseWhitespace: true, 66 | removeRedundantAttributes: true, 67 | useShortDoctype: true, 68 | removeEmptyAttributes: true, 69 | removeStyleLinkTypeAttributes: true, 70 | keepClosingSlash: true, 71 | minifyJS: true, 72 | minifyCSS: true, 73 | minifyURLs: true 74 | } 75 | }), 76 | new CleanWebpackPlugin(['docs'], { 77 | verbose: true 78 | }), 79 | // Minify the compiled JavaScript. 80 | new webpack.optimize.UglifyJsPlugin({ 81 | compress: { 82 | warnings: false 83 | }, 84 | output: { 85 | comments: false 86 | } 87 | }), 88 | ] 89 | }; --------------------------------------------------------------------------------