diff --git a/404.html b/404.html index cb3e6ca6..6f99e421 100644 --- a/404.html +++ b/404.html @@ -5,8 +5,8 @@ Arrow - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

diff --git a/assets/js/09ddf926.1c00db1f.js b/assets/js/09ddf926.c0bfb142.js similarity index 76% rename from assets/js/09ddf926.1c00db1f.js rename to assets/js/09ddf926.c0bfb142.js index 29104caa..dcc08d50 100644 --- a/assets/js/09ddf926.1c00db1f.js +++ b/assets/js/09ddf926.c0bfb142.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[6496],{85979:a=>{a.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":46,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/5","page":5,"postsPerPage":8,"totalPages":6,"totalCount":46,"previousPage":"/community/blog/tags/articles/page/4","nextPage":"/community/blog/tags/articles/page/6","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[6496],{85979:a=>{a.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":47,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/5","page":5,"postsPerPage":8,"totalPages":6,"totalCount":47,"previousPage":"/community/blog/tags/articles/page/4","nextPage":"/community/blog/tags/articles/page/6","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/148a328e.9b4916b8.js b/assets/js/148a328e.9853f48d.js similarity index 82% rename from assets/js/148a328e.9b4916b8.js rename to assets/js/148a328e.9853f48d.js index bad9afb8..1e817b3e 100644 --- a/assets/js/148a328e.9b4916b8.js +++ b/assets/js/148a328e.9853f48d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7847],{6290:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/13","page":13,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/12","nextPage":"/community/blog/page/14","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7847],{6290:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/13","page":13,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/12","nextPage":"/community/blog/page/14","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/17cd98fd.dca26c82.js b/assets/js/17cd98fd.ca29ed37.js similarity index 82% rename from assets/js/17cd98fd.dca26c82.js rename to assets/js/17cd98fd.ca29ed37.js index 2c53f996..2989e255 100644 --- a/assets/js/17cd98fd.dca26c82.js +++ b/assets/js/17cd98fd.ca29ed37.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[6684],{86050:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/4","page":4,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/3","nextPage":"/community/blog/page/5","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[6684],{86050:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/4","page":4,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/3","nextPage":"/community/blog/page/5","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/199e9947.87e2f020.js b/assets/js/199e9947.2f0ea7d6.js similarity index 82% rename from assets/js/199e9947.87e2f020.js rename to assets/js/199e9947.2f0ea7d6.js index fbc8be5d..ad490666 100644 --- a/assets/js/199e9947.87e2f020.js +++ b/assets/js/199e9947.2f0ea7d6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3120],{28817:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/3","page":3,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/2","nextPage":"/community/blog/page/4","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3120],{28817:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/3","page":3,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/2","nextPage":"/community/blog/page/4","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/1df93b7f.0254e93d.js b/assets/js/1df93b7f.0254e93d.js deleted file mode 100644 index fd4b9bff..00000000 --- a/assets/js/1df93b7f.0254e93d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3237],{8730:(e,t,a)=>{a.d(t,{T:()=>o});a(67294);var r=a(33692),i=a(44996);const n={borderlessCard:"borderlessCard_sjEN",infoMode:"infoMode_oa1U",icon:"icon_c5iy",cardHeader:"cardHeader_Melu",title:"title_AiRZ",cardBody:"cardBody__x5U",cardFooter:"cardFooter_BYOD",link:"link_YPJo"};var s=a(85893);function o(e){let{title:t,icon:a,href:o,body:c}=e;const l=!o,d=l?"64px":"32px";return(0,s.jsxs)("div",{className:`card ${n.borderlessCard} ${l&&n.infoMode}`,children:[(0,s.jsxs)("div",{className:`card__header ${n.cardHeader}`,children:[(0,s.jsx)("img",{className:n.icon,src:(0,i.Z)(`/img/${a}`),alt:`${t} category`,title:`${t} category`,height:d,width:d}),(0,s.jsx)("h3",{className:n.title,children:t})]}),(0,s.jsx)("div",{className:`card__body ${n.cardBody}`,children:(0,s.jsx)("p",{children:c})}),!l&&(0,s.jsx)("div",{className:`card__footer ${n.cardFooter}`,children:(0,s.jsx)("strong",{children:(0,s.jsx)(r.Z,{href:o,className:n.link,children:"Learn more"})})})]})}},78914:(e,t,a)=>{a.d(t,{V:()=>s});a(67294);var r=a(33692);const i={hero:"hero_wgFg",container:"container_Iw7w",subtitle:"subtitle_oBSE",ctaList:"ctaList_HWQC"};var n=a(85893);function s(e){let{title:t,subtitle:a,ctaList:s,className:o}=e;return(0,n.jsx)("div",{className:`hero ${i.hero} ${o}`,children:(0,n.jsxs)("div",{className:`container ${i.container}`,children:[(0,n.jsx)("h1",{className:"hero__title",children:t}),a&&(0,n.jsx)("h2",{className:i.subtitle,children:a}),(0,n.jsx)("div",{className:i.ctaList,children:s&&s.map((e=>{let{title:t,href:a}=e;return(0,n.jsx)(r.Z,{href:a,className:"button button--primary button--lg",children:t},t)}))})]})})}},66569:(e,t,a)=>{a.d(t,{k:()=>u});a(67294);var r=a(33692),i=a(44996);const n="linkCard_uxt7",s="icon_lqTJ",o="cardHeader_NaDd",c="cardBody_svEQ",l="paragraph_UbEf";var d=a(85893);function h(e){let{href:t,children:a}=e;return(0,d.jsx)(r.Z,{href:t,className:n,children:a})}function m(e){let{title:t,icon:a,body:r}=e;return(0,d.jsxs)("div",{className:"card",children:[(0,d.jsxs)("div",{className:`card__header ${o}`,children:[(0,d.jsx)("img",{className:s,src:(0,i.Z)(`/img/${a}`),alt:`${t} category`,title:`${t} category`,width:"48px",height:"48px"}),(0,d.jsx)("h2",{title:t,className:"text--truncate",children:t})]}),(0,d.jsx)("div",{className:`card__body ${c}`,children:(0,d.jsx)("p",{className:`${l}`,children:r})})]})}const u=e=>(0,d.jsx)(h,{href:e.href,children:(0,d.jsx)(m,{...e})})},3e4:(e,t,a)=>{a.d(t,{P:()=>s});a(67294);var r=a(44996);const i={quoteCard:"quoteCard_rWDi"};var n=a(85893);function s(e){let{name:t,position:a,image:s,body:o}=e;return(0,n.jsxs)("div",{className:`card ${i.quoteCard}`,children:[(0,n.jsx)("div",{className:"card__body",children:(0,n.jsx)("p",{children:o})}),(0,n.jsxs)("div",{className:"card__footer avatar",children:[s&&(0,n.jsx)("div",{className:"avatar__photo-wrapper",children:(0,n.jsx)("img",{className:"avatar__photo",src:(0,r.Z)(`/img/${s}`),alt:t,title:t})}),(0,n.jsxs)("div",{className:"avatar__intro",children:[(0,n.jsx)("div",{className:"avatar__name",children:t}),(0,n.jsx)("small",{className:"avatar__subtitle",children:a})]})]})]})}},83666:(e,t,a)=>{a.r(t),a.d(t,{default:()=>g});a(67294);var r=a(47311),i=a(52263),n=a(44996),s=a(70307),o=a(78914),c=a(66569),l=a(3e4),d=a(8730);const h={hero:{title:"Arrow brings idiomatic functional programming to Kotlin",ctaList:[{title:"What is Arrow",href:"/learn/overview"},{title:"Get Started",href:"/learn/quickstart"}]},features:[{title:"Quickstart",href:"/learn/quickstart",icon:"icon-quickstart.svg",body:"Gradle or Maven, JVM or Multiplatform, Arrow fits in all your projects"},{title:"Typed errors",href:"/learn/typed-errors",icon:"icon-typed-errors.svg",body:"Structured, predictable, and efficient handling of errors"},{title:"Coroutines",href:"/learn/coroutines",icon:"icon-coroutines.svg",body:"High-level utilities for working with coroutines, and correctly managing resources and shared data"},{title:"Resilience",href:"/learn/resilience",icon:"icon-resilience.svg",body:"Make your code respond to failures in an organized way"},{title:"Immutable data",href:"/learn/immutable-data",icon:"icon-immutable-data.svg",body:"Great tooling for dealing with immutable data and sealed hierarchies"},{title:"Collections and functions",href:"/learn/collections-functions",icon:"icon-generic-6.svg",body:"Powerful additions to the basics to make your code more expressive"}],quotes:[{name:"George Popides",position:"Software Engineer at Katanox",body:"Our system consists of multiple services built with Kotlin and Spring Boot and the communication between the services is done through GRPC. The more services involved the more the failure points which means we need a streamlined way to handle failures and errors without affecting the operation of our system. [..] By using Either and Validated, we have eliminated unexpected exceptions in our system and we can now have a look on errors through our logs without worrying about unexpected exceptions that can bring our system down"},{name:"Ilyan Germanov",position:"Co-founder of Ivy Apps",body:"This week, I'm into sharing things that made my life as an Android developer with Kotlin easier. In my opinion, functional programming is an awesome paradigm and can be a first-class citizen in Kotlin. [..] Arrow is a \"Functional companion to Kotlin's Standard Library\" and provides the core constructs from the FP world to get you started."}]},m={verticalRhythm:"verticalRhythm_yh8W",textContainer:"textContainer_n5O4",featuresContainer:"featuresContainer_hwgM container",quotesContainer:"quotesContainer__Qcv container",projectsContainer:"projectsContainer_IRh5",navigationContainer:"navigationContainer_Aik1",usageWrapperContainer:"usageWrapperContainer_uUHj",usageContainer:"usageContainer_sNYk"};var u=a(85893);function g(){const{siteConfig:e}=(0,i.Z)();return(0,u.jsxs)(s.Z,{description:e.tagline,children:[(0,u.jsx)(o.V,{title:(0,r.ZP)(h.hero.title),ctaList:h.hero.ctaList,className:m.verticalRhythm}),(0,u.jsxs)("main",{children:[(0,u.jsxs)("section",{className:`container text--center ${m.textContainer} ${m.verticalRhythm}`,children:[(0,u.jsx)("h1",{children:"Start learning now"}),(0,u.jsx)("p",{children:"Arrow is composed of different libraries that greatly improve your developer experience using Kotlin"})]}),(0,u.jsx)("section",{className:`${m.featuresContainer} ${m.verticalRhythm}`,children:h.features.map((e=>(0,u.jsx)(c.k,{...e},e.title)))}),(0,u.jsxs)("section",{className:`container text--center margin-bottom--lg ${m.textContainer}`,children:[(0,u.jsx)("h1",{children:"What the community says"}),(0,u.jsx)("p",{children:"Some opinions about Arrow from the community and its practitioners"})]}),(0,u.jsx)("section",{className:`${m.quotesContainer} ${m.verticalRhythm}`,children:h.quotes?.map((e=>(0,u.jsx)(l.P,{...e},e.name)))}),h.navs&&(0,u.jsx)("section",{className:`container ${m.navigationContainer} ${m.verticalRhythm}`,children:h.navs.map((e=>(0,u.jsx)(d.T,{...e},e.title)))}),(0,u.jsx)("section",{className:`${m.usageWrapperContainer}`,children:(0,u.jsx)("div",{className:`container ${m.usageContainer}`,children:h.companies?.map((e=>(0,u.jsx)("img",{src:(0,n.Z)(`/img/${e.logo}`),alt:e.name,title:e.name},e.name)))})})]})]})}}}]); \ No newline at end of file diff --git a/assets/js/1df93b7f.cc2ee245.js b/assets/js/1df93b7f.cc2ee245.js new file mode 100644 index 00000000..577ecc68 --- /dev/null +++ b/assets/js/1df93b7f.cc2ee245.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3237],{8730:(e,t,a)=>{a.d(t,{T:()=>o});a(67294);var r=a(33692),i=a(44996);const n={borderlessCard:"borderlessCard_sjEN",infoMode:"infoMode_oa1U",icon:"icon_c5iy",cardHeader:"cardHeader_Melu",title:"title_AiRZ",cardBody:"cardBody__x5U",cardFooter:"cardFooter_BYOD",link:"link_YPJo"};var s=a(85893);function o(e){let{title:t,icon:a,href:o,body:c}=e;const l=!o,d=l?"64px":"32px";return(0,s.jsxs)("div",{className:`card ${n.borderlessCard} ${l&&n.infoMode}`,children:[(0,s.jsxs)("div",{className:`card__header ${n.cardHeader}`,children:[(0,s.jsx)("img",{className:n.icon,src:(0,i.Z)(`/img/${a}`),alt:`${t} category`,title:`${t} category`,height:d,width:d}),(0,s.jsx)("h3",{className:n.title,children:t})]}),(0,s.jsx)("div",{className:`card__body ${n.cardBody}`,children:(0,s.jsx)("p",{children:c})}),!l&&(0,s.jsx)("div",{className:`card__footer ${n.cardFooter}`,children:(0,s.jsx)("strong",{children:(0,s.jsx)(r.Z,{href:o,className:n.link,children:"Learn more"})})})]})}},78914:(e,t,a)=>{a.d(t,{V:()=>s});a(67294);var r=a(33692);const i={hero:"hero_wgFg",container:"container_Iw7w",subtitle:"subtitle_oBSE",ctaList:"ctaList_HWQC"};var n=a(85893);function s(e){let{title:t,subtitle:a,ctaList:s,className:o}=e;return(0,n.jsx)("div",{className:`hero ${i.hero} ${o}`,children:(0,n.jsxs)("div",{className:`container ${i.container}`,children:[(0,n.jsx)("h1",{className:"hero__title",children:t}),a&&(0,n.jsx)("h2",{className:i.subtitle,children:a}),(0,n.jsx)("div",{className:i.ctaList,children:s&&s.map((e=>{let{title:t,href:a}=e;return(0,n.jsx)(r.Z,{href:a,className:"button button--primary button--lg",children:t},t)}))})]})})}},66569:(e,t,a)=>{a.d(t,{k:()=>u});a(67294);var r=a(33692),i=a(44996);const n="linkCard_uxt7",s="icon_lqTJ",o="cardHeader_NaDd",c="cardBody_svEQ",l="paragraph_UbEf";var d=a(85893);function h(e){let{href:t,children:a}=e;return(0,d.jsx)(r.Z,{href:t,className:n,children:a})}function m(e){let{title:t,icon:a,body:r}=e;return(0,d.jsxs)("div",{className:"card",children:[(0,d.jsxs)("div",{className:`card__header ${o}`,children:[(0,d.jsx)("img",{className:s,src:(0,i.Z)(`/img/${a}`),alt:`${t} category`,title:`${t} category`,width:"48px",height:"48px"}),(0,d.jsx)("h2",{title:t,className:"text--truncate",children:t})]}),(0,d.jsx)("div",{className:`card__body ${c}`,children:(0,d.jsx)("p",{className:`${l}`,children:r})})]})}const u=e=>(0,d.jsx)(h,{href:e.href,children:(0,d.jsx)(m,{...e})})},3e4:(e,t,a)=>{a.d(t,{P:()=>s});a(67294);var r=a(44996);const i={quoteCard:"quoteCard_rWDi"};var n=a(85893);function s(e){let{name:t,position:a,image:s,body:o}=e;return(0,n.jsxs)("div",{className:`card ${i.quoteCard}`,children:[(0,n.jsx)("div",{className:"card__body",children:(0,n.jsx)("p",{children:o})}),(0,n.jsxs)("div",{className:"card__footer avatar",children:[s&&(0,n.jsx)("div",{className:"avatar__photo-wrapper",children:(0,n.jsx)("img",{className:"avatar__photo",src:(0,r.Z)(`/img/${s}`),alt:t,title:t})}),(0,n.jsxs)("div",{className:"avatar__intro",children:[(0,n.jsx)("div",{className:"avatar__name",children:t}),(0,n.jsx)("small",{className:"avatar__subtitle",children:a})]})]})]})}},83666:(e,t,a)=>{a.r(t),a.d(t,{default:()=>g});a(67294);var r=a(47311),i=a(52263),n=a(44996),s=a(70307),o=a(78914),c=a(66569),l=a(3e4),d=a(8730);const h={hero:{title:"Arrow brings idiomatic functional programming to Kotlin",ctaList:[{title:"What is Arrow",href:"/learn/overview"},{title:"Get Started",href:"/learn/quickstart"},{title:"Open Space @ Lambda World",href:"/community/blog/2024/10/03/arrow-open-space/"}]},features:[{title:"Quickstart",href:"/learn/quickstart",icon:"icon-quickstart.svg",body:"Gradle or Maven, JVM or Multiplatform, Arrow fits in all your projects"},{title:"Typed errors",href:"/learn/typed-errors",icon:"icon-typed-errors.svg",body:"Structured, predictable, and efficient handling of errors"},{title:"Coroutines",href:"/learn/coroutines",icon:"icon-coroutines.svg",body:"High-level utilities for working with coroutines, and correctly managing resources and shared data"},{title:"Resilience",href:"/learn/resilience",icon:"icon-resilience.svg",body:"Make your code respond to failures in an organized way"},{title:"Immutable data",href:"/learn/immutable-data",icon:"icon-immutable-data.svg",body:"Great tooling for dealing with immutable data and sealed hierarchies"},{title:"Collections and functions",href:"/learn/collections-functions",icon:"icon-generic-6.svg",body:"Powerful additions to the basics to make your code more expressive"}],quotes:[{name:"George Popides",position:"Software Engineer at Katanox",body:"Our system consists of multiple services built with Kotlin and Spring Boot and the communication between the services is done through GRPC. The more services involved the more the failure points which means we need a streamlined way to handle failures and errors without affecting the operation of our system. [..] By using Either and Validated, we have eliminated unexpected exceptions in our system and we can now have a look on errors through our logs without worrying about unexpected exceptions that can bring our system down"},{name:"Ilyan Germanov",position:"Co-founder of Ivy Apps",body:"This week, I'm into sharing things that made my life as an Android developer with Kotlin easier. In my opinion, functional programming is an awesome paradigm and can be a first-class citizen in Kotlin. [..] Arrow is a \"Functional companion to Kotlin's Standard Library\" and provides the core constructs from the FP world to get you started."}]},m={verticalRhythm:"verticalRhythm_yh8W",textContainer:"textContainer_n5O4",featuresContainer:"featuresContainer_hwgM container",quotesContainer:"quotesContainer__Qcv container",projectsContainer:"projectsContainer_IRh5",navigationContainer:"navigationContainer_Aik1",usageWrapperContainer:"usageWrapperContainer_uUHj",usageContainer:"usageContainer_sNYk"};var u=a(85893);function g(){const{siteConfig:e}=(0,i.Z)();return(0,u.jsxs)(s.Z,{description:e.tagline,children:[(0,u.jsx)(o.V,{title:(0,r.ZP)(h.hero.title),ctaList:h.hero.ctaList,className:m.verticalRhythm}),(0,u.jsxs)("main",{children:[(0,u.jsxs)("section",{className:`container text--center ${m.textContainer} ${m.verticalRhythm}`,children:[(0,u.jsx)("h1",{children:"Start learning now"}),(0,u.jsx)("p",{children:"Arrow is composed of different libraries that greatly improve your developer experience using Kotlin"})]}),(0,u.jsx)("section",{className:`${m.featuresContainer} ${m.verticalRhythm}`,children:h.features.map((e=>(0,u.jsx)(c.k,{...e},e.title)))}),(0,u.jsxs)("section",{className:`container text--center margin-bottom--lg ${m.textContainer}`,children:[(0,u.jsx)("h1",{children:"What the community says"}),(0,u.jsx)("p",{children:"Some opinions about Arrow from the community and its practitioners"})]}),(0,u.jsx)("section",{className:`${m.quotesContainer} ${m.verticalRhythm}`,children:h.quotes?.map((e=>(0,u.jsx)(l.P,{...e},e.name)))}),h.navs&&(0,u.jsx)("section",{className:`container ${m.navigationContainer} ${m.verticalRhythm}`,children:h.navs.map((e=>(0,u.jsx)(d.T,{...e},e.title)))}),(0,u.jsx)("section",{className:`${m.usageWrapperContainer}`,children:(0,u.jsx)("div",{className:`container ${m.usageContainer}`,children:h.companies?.map((e=>(0,u.jsx)("img",{src:(0,n.Z)(`/img/${e.logo}`),alt:e.name,title:e.name},e.name)))})})]})]})}}}]); \ No newline at end of file diff --git a/assets/js/24a5a52d.46c959ab.js b/assets/js/24a5a52d.2eee9cde.js similarity index 79% rename from assets/js/24a5a52d.46c959ab.js rename to assets/js/24a5a52d.2eee9cde.js index 7c1c9689..3b05c811 100644 --- a/assets/js/24a5a52d.46c959ab.js +++ b/assets/js/24a5a52d.2eee9cde.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[4855],{28128:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog","page":1,"postsPerPage":8,"totalPages":14,"totalCount":106,"nextPage":"/community/blog/page/2","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[4855],{28128:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog","page":1,"postsPerPage":8,"totalPages":14,"totalCount":107,"nextPage":"/community/blog/page/2","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/27fc5ece.6b946672.js b/assets/js/27fc5ece.5b76a8ce.js similarity index 82% rename from assets/js/27fc5ece.6b946672.js rename to assets/js/27fc5ece.5b76a8ce.js index 92328e40..1f095056 100644 --- a/assets/js/27fc5ece.6b946672.js +++ b/assets/js/27fc5ece.5b76a8ce.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[778],{76112:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/2","page":2,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog","nextPage":"/community/blog/page/3","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[778],{76112:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/2","page":2,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog","nextPage":"/community/blog/page/3","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/320d88c4.c4755d5b.js b/assets/js/320d88c4.0d52a8b8.js similarity index 99% rename from assets/js/320d88c4.c4755d5b.js rename to assets/js/320d88c4.0d52a8b8.js index 4e134425..a190f953 100644 --- a/assets/js/320d88c4.c4755d5b.js +++ b/assets/js/320d88c4.0d52a8b8.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3910],{39748:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=t(85893),a=t(11151);const i={id:"compose",title:"Compose and UIs",sidebar_position:3},s=void 0,o={id:"learn/quickstart/compose",title:"Compose and UIs",description:"Arrow provides several features which are very interesting when developing",source:"@site/content/docs/learn/quickstart/compose.md",sourceDirName:"learn/quickstart",slug:"/learn/quickstart/compose",permalink:"/learn/quickstart/compose",draft:!1,unlisted:!1,editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/docs/learn/quickstart/compose.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{id:"compose",title:"Compose and UIs",sidebar_position:3},sidebar:"learnSidebar",previous:{title:"Serialization",permalink:"/learn/quickstart/serialization"},next:{title:"Migration to Arrow 1.2.0",permalink:"/learn/quickstart/migration"}},l={},c=[{value:"Compose is functional",id:"compose-is-functional",level:2},{value:"Simpler effectful code",id:"simpler-effectful-code",level:2},{value:"Built-in error types",id:"built-in-error-types",level:2},{value:"Updating the model",id:"updating-the-model",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"Arrow provides several features which are very interesting when developing\ninteractive applications, especially in combination with libraries with a\nsimilar functional flavor, such as Compose."}),"\n",(0,r.jsx)(n.admonition,{title:"Example projects",type:"info",children:(0,r.jsxs)(n.p,{children:["Projects using Compose and Arrow can be found in the\n",(0,r.jsx)(n.a,{href:"../../design/projects/",children:"corresponding section"}),"."]})}),"\n",(0,r.jsx)(n.admonition,{title:"Multiplatform-ready",type:"note",children:(0,r.jsxs)(n.p,{children:["All the libraries under the Arrow umbrella are\n",(0,r.jsx)(n.a,{href:"https://kotlinlang.org/docs/multiplatform.html",children:"Multiplatform"}),"-ready.\nThis means you can use them in your Android applications using\n",(0,r.jsx)(n.a,{href:"https://developer.android.com/jetpack/compose",children:"Jetpack Compose"}),",\nand in Desktop, iOS, or Web alongside\n",(0,r.jsx)(n.a,{href:"https://www.jetbrains.com/lp/compose-multiplatform/",children:"Compose Multiplaftorm"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"compose-is-functional",children:"Compose is functional"}),"\n",(0,r.jsxs)(n.p,{children:["As opposed to other frameworks where stateful components are the norm, the\n",(0,r.jsx)(n.a,{href:"https://developer.android.com/jetpack/compose/architecture",children:"architecture"}),"\npromoted by Compose brings many concepts traditionally associated with a\nmore functional approach. For example, the UI is defined as a ",(0,r.jsx)(n.em,{children:"function"}),"\ntaking as arguments the ",(0,r.jsx)(n.em,{children:"values"})," from the current state. Updating the state\nis also explicitly marked, and often separated in a ",(0,r.jsx)(n.code,{children:"ViewModel"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["As a consequence, Arrow and Compose make great dancing partners. Below we\ndiscuss a few feature which we think are an immediately gain for Android\n(and with Compose Multiplatform, other UI) developers. In the same vein, our\n",(0,r.jsx)(n.a,{href:"../../design/",children:"design"})," section readily applies to projects using Compose."]}),"\n",(0,r.jsx)(n.h2,{id:"simpler-effectful-code",children:"Simpler effectful code"}),"\n",(0,r.jsxs)(n.p,{children:["Most applications don't live in a vacuum, they need to access other services\nor data sources. In those cases we write ",(0,r.jsx)(n.em,{children:"effectful"})," code, where ",(0,r.jsx)(n.code,{children:"suspend"})," and\ncoroutines become relevant."]}),"\n",(0,r.jsxs)(n.p,{children:["Arrow Fx introduces\n",(0,r.jsx)(n.a,{href:"../../coroutines/parallel/",children:"high-level concurrency"})," as a way to simplify code\nwhere different actions must happen concurrently, ensuring that all rules\nof Structured Concurrency are followed, but without the hassle."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"class UserSettingsModel: ViewModel() {\n private val _userData = mutableStateOf(null)\n val userData: State get() = _userData\n\n suspend fun loadUserData(userId: UserId) =\n parZip(\n { downloadAvatar(userId) },\n { UserRepository.getById(userId) }\n ) { avatarFile, user ->\n // this code is called once both finish\n _userData.value = UserData(\n id = userId,\n details = user,\n avatar = Avatar(avatarFile)\n )\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Anything outside your own application is the wilderness: connections are\ndown, services are unavailable. Arrow's ",(0,r.jsx)(n.a,{href:"../../resilience/",children:"resilience"}),"\nmodule provides several ready-to-use patterns to better handle those situations,\nincluding ",(0,r.jsx)(n.a,{href:"../../resilience/retry-and-repeat/",children:"retry policies"}),"\nand ",(0,r.jsx)(n.a,{href:"../../resilience/circuitbreaker/",children:"circuit breakers"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"built-in-error-types",children:"Built-in error types"}),"\n",(0,r.jsxs)(n.p,{children:["One key part of every application is how the domain is modelled.\nArrow emphasizes using ",(0,r.jsx)(n.a,{href:"../../design/domain-modeling/",children:"immutable data"}),".\nIn particular, sealed hierarchies take the important role of describing the\ndifferent states."]}),"\n",(0,r.jsxs)(n.p,{children:['Although every application is unique, a common scenario in interactive\napplications involve having a "success state" and an "error state".\nFor example, correctly loading the user data, or encountering a problem\nwith connection or authentication. Instead of rolling your own types,\nArrow (and our sibling library ',(0,r.jsx)(n.a,{href:"https://cashapp.github.io/quiver/",children:"Quiver"}),")\nprovide out-of-the-box solutions:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"../../typed-errors/either-and-ior/",children:(0,r.jsx)(n.code,{children:"Either"})})," describes a model\nin which the application has either completely succeeded, or\nsome amount of errors have occured. Validation is a prime example,\nsince we usually require for all fields to be valid before\nmoving forward with the data."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"../../typed-errors/either-and-ior/",children:(0,r.jsx)(n.code,{children:"Ior"})})," introduces a third\noption, namely succeeding but still with some problems along the way.\nThis type is useful to model domains where we can work with some\nerroneous or missing information."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://cashapp.github.io/quiver/-quiver%20-library/app.cash.quiver/-outcome/index.html",children:(0,r.jsx)(n.code,{children:"Outcome"})}),"\nmodels success, failure, and absence. The latter case is useful\nwhen the application may be in ",(0,r.jsx)(n.em,{children:"loading"})," state: still no problems,\nbut no data ready either."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Given the commonalities, Arrow provides a ",(0,r.jsx)(n.a,{href:"../../typed-errors/working-with-typed-errors/",children:"uniform API"}),"\nto work with values of those types."]}),"\n",(0,r.jsx)(n.h2,{id:"updating-the-model",children:"Updating the model"}),"\n",(0,r.jsxs)(n.p,{children:["One potential drawback of using\n",(0,r.jsx)(n.a,{href:"../../design/domain-modeling/",children:"immutable data to model your state"}),"\nis that updating it can become quite tiresome, because Kotlin provides\nno dedicated feature other than ",(0,r.jsx)(n.code,{children:"copy"})," for this task."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"class UserSettingsModel: ViewModel() {\n private val _userData = mutableStateOf(null)\n val userData: State get() = _userData\n\n fun updateName(\n newFirstName: String, newLastName: String\n ) {\n _userData.value = _userData.value.copy(\n details = _userData.value.details.copy(\n name = _userData.value.details.name.copy(\n firstName = newFirstName, lastName = newLastName\n )\n )\n )\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Arrow Optics addresses these drawbacks, providing\n",(0,r.jsxs)(n.a,{href:"../../immutable-data/intro/",children:["tools for manipulating and transforming ",(0,r.jsx)(n.em,{children:"immutable"})," data"]}),".\nThe code above can be rewritten without boring repetition using\nthe ",(0,r.jsxs)(n.a,{href:"../../immutable-data/lens/#more-powerful-copy",children:["dedicated ",(0,r.jsx)(n.code,{children:"copy"})," for ",(0,r.jsx)(n.code,{children:"MutableState"})]}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"class UserSettingsModel: ViewModel() {\n private val _userData = mutableStateOf(null)\n val userData: State get() = _userData\n\n fun updateName(\n newFirstName: String, newLastName: String\n ) {\n _userData.updateCopy {\n inside(UserData.details.name) {\n Name.firstName set newFirstName\n Name.lastName set newLastName\n }\n }\n }\n}\n"})})]})}function u(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>s});var r=t(67294);const a={},i=r.createContext(a);function s(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3910],{39748:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=t(85893),a=t(11151);const i={id:"compose",title:"Compose and UIs",sidebar_position:3},s=void 0,o={id:"learn/quickstart/compose",title:"Compose and UIs",description:"Arrow provides several features which are very interesting when developing",source:"@site/content/docs/learn/quickstart/compose.md",sourceDirName:"learn/quickstart",slug:"/learn/quickstart/compose",permalink:"/learn/quickstart/compose",draft:!1,unlisted:!1,editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/docs/learn/quickstart/compose.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{id:"compose",title:"Compose and UIs",sidebar_position:3},sidebar:"learnSidebar",previous:{title:"Serialization",permalink:"/learn/quickstart/serialization"},next:{title:"Migration to Arrow 1.2.0",permalink:"/learn/quickstart/migration"}},l={},c=[{value:"Compose is functional",id:"compose-is-functional",level:2},{value:"Simpler effectful code",id:"simpler-effectful-code",level:2},{value:"Built-in error types",id:"built-in-error-types",level:2},{value:"Updating the model",id:"updating-the-model",level:2}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",li:"li",p:"p",pre:"pre",ul:"ul",...(0,a.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.p,{children:"Arrow provides several features which are very interesting when developing\ninteractive applications, especially in combination with libraries with a\nsimilar functional flavor, such as Compose."}),"\n",(0,r.jsx)(n.admonition,{title:"Example projects",type:"info",children:(0,r.jsxs)(n.p,{children:["Projects using Compose and Arrow can be found in the\n",(0,r.jsx)(n.a,{href:"../../design/projects/",children:"corresponding section"}),"."]})}),"\n",(0,r.jsx)(n.admonition,{title:"Multiplatform-ready",type:"note",children:(0,r.jsxs)(n.p,{children:["All the libraries under the Arrow umbrella are\n",(0,r.jsx)(n.a,{href:"https://kotlinlang.org/docs/multiplatform.html",children:"Multiplatform"}),"-ready.\nThis means you can use them in your Android applications using\n",(0,r.jsx)(n.a,{href:"https://developer.android.com/jetpack/compose",children:"Jetpack Compose"}),",\nand in Desktop, iOS, or Web alongside\n",(0,r.jsx)(n.a,{href:"https://www.jetbrains.com/lp/compose-multiplatform/",children:"Compose Multiplatform"}),"."]})}),"\n",(0,r.jsx)(n.h2,{id:"compose-is-functional",children:"Compose is functional"}),"\n",(0,r.jsxs)(n.p,{children:["As opposed to other frameworks where stateful components are the norm, the\n",(0,r.jsx)(n.a,{href:"https://developer.android.com/jetpack/compose/architecture",children:"architecture"}),"\npromoted by Compose brings many concepts traditionally associated with a\nmore functional approach. For example, the UI is defined as a ",(0,r.jsx)(n.em,{children:"function"}),"\ntaking as arguments the ",(0,r.jsx)(n.em,{children:"values"})," from the current state. Updating the state\nis also explicitly marked, and often separated in a ",(0,r.jsx)(n.code,{children:"ViewModel"}),"."]}),"\n",(0,r.jsxs)(n.p,{children:["As a consequence, Arrow and Compose make great dancing partners. Below we\ndiscuss a few feature which we think are an immediately gain for Android\n(and with Compose Multiplatform, other UI) developers. In the same vein, our\n",(0,r.jsx)(n.a,{href:"../../design/",children:"design"})," section readily applies to projects using Compose."]}),"\n",(0,r.jsx)(n.h2,{id:"simpler-effectful-code",children:"Simpler effectful code"}),"\n",(0,r.jsxs)(n.p,{children:["Most applications don't live in a vacuum, they need to access other services\nor data sources. In those cases we write ",(0,r.jsx)(n.em,{children:"effectful"})," code, where ",(0,r.jsx)(n.code,{children:"suspend"})," and\ncoroutines become relevant."]}),"\n",(0,r.jsxs)(n.p,{children:["Arrow Fx introduces\n",(0,r.jsx)(n.a,{href:"../../coroutines/parallel/",children:"high-level concurrency"})," as a way to simplify code\nwhere different actions must happen concurrently, ensuring that all rules\nof Structured Concurrency are followed, but without the hassle."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"class UserSettingsModel: ViewModel() {\n private val _userData = mutableStateOf(null)\n val userData: State get() = _userData\n\n suspend fun loadUserData(userId: UserId) =\n parZip(\n { downloadAvatar(userId) },\n { UserRepository.getById(userId) }\n ) { avatarFile, user ->\n // this code is called once both finish\n _userData.value = UserData(\n id = userId,\n details = user,\n avatar = Avatar(avatarFile)\n )\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Anything outside your own application is the wilderness: connections are\ndown, services are unavailable. Arrow's ",(0,r.jsx)(n.a,{href:"../../resilience/",children:"resilience"}),"\nmodule provides several ready-to-use patterns to better handle those situations,\nincluding ",(0,r.jsx)(n.a,{href:"../../resilience/retry-and-repeat/",children:"retry policies"}),"\nand ",(0,r.jsx)(n.a,{href:"../../resilience/circuitbreaker/",children:"circuit breakers"}),"."]}),"\n",(0,r.jsx)(n.h2,{id:"built-in-error-types",children:"Built-in error types"}),"\n",(0,r.jsxs)(n.p,{children:["One key part of every application is how the domain is modelled.\nArrow emphasizes using ",(0,r.jsx)(n.a,{href:"../../design/domain-modeling/",children:"immutable data"}),".\nIn particular, sealed hierarchies take the important role of describing the\ndifferent states."]}),"\n",(0,r.jsxs)(n.p,{children:['Although every application is unique, a common scenario in interactive\napplications involve having a "success state" and an "error state".\nFor example, correctly loading the user data, or encountering a problem\nwith connection or authentication. Instead of rolling your own types,\nArrow (and our sibling library ',(0,r.jsx)(n.a,{href:"https://cashapp.github.io/quiver/",children:"Quiver"}),")\nprovide out-of-the-box solutions:"]}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"../../typed-errors/either-and-ior/",children:(0,r.jsx)(n.code,{children:"Either"})})," describes a model\nin which the application has either completely succeeded, or\nsome amount of errors have occured. Validation is a prime example,\nsince we usually require for all fields to be valid before\nmoving forward with the data."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"../../typed-errors/either-and-ior/",children:(0,r.jsx)(n.code,{children:"Ior"})})," introduces a third\noption, namely succeeding but still with some problems along the way.\nThis type is useful to model domains where we can work with some\nerroneous or missing information."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.a,{href:"https://cashapp.github.io/quiver/-quiver%20-library/app.cash.quiver/-outcome/index.html",children:(0,r.jsx)(n.code,{children:"Outcome"})}),"\nmodels success, failure, and absence. The latter case is useful\nwhen the application may be in ",(0,r.jsx)(n.em,{children:"loading"})," state: still no problems,\nbut no data ready either."]}),"\n"]}),"\n",(0,r.jsxs)(n.p,{children:["Given the commonalities, Arrow provides a ",(0,r.jsx)(n.a,{href:"../../typed-errors/working-with-typed-errors/",children:"uniform API"}),"\nto work with values of those types."]}),"\n",(0,r.jsx)(n.h2,{id:"updating-the-model",children:"Updating the model"}),"\n",(0,r.jsxs)(n.p,{children:["One potential drawback of using\n",(0,r.jsx)(n.a,{href:"../../design/domain-modeling/",children:"immutable data to model your state"}),"\nis that updating it can become quite tiresome, because Kotlin provides\nno dedicated feature other than ",(0,r.jsx)(n.code,{children:"copy"})," for this task."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"class UserSettingsModel: ViewModel() {\n private val _userData = mutableStateOf(null)\n val userData: State get() = _userData\n\n fun updateName(\n newFirstName: String, newLastName: String\n ) {\n _userData.value = _userData.value.copy(\n details = _userData.value.details.copy(\n name = _userData.value.details.name.copy(\n firstName = newFirstName, lastName = newLastName\n )\n )\n )\n }\n}\n"})}),"\n",(0,r.jsxs)(n.p,{children:["Arrow Optics addresses these drawbacks, providing\n",(0,r.jsxs)(n.a,{href:"../../immutable-data/intro/",children:["tools for manipulating and transforming ",(0,r.jsx)(n.em,{children:"immutable"})," data"]}),".\nThe code above can be rewritten without boring repetition using\nthe ",(0,r.jsxs)(n.a,{href:"../../immutable-data/lens/#more-powerful-copy",children:["dedicated ",(0,r.jsx)(n.code,{children:"copy"})," for ",(0,r.jsx)(n.code,{children:"MutableState"})]}),"."]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-kotlin",children:"class UserSettingsModel: ViewModel() {\n private val _userData = mutableStateOf(null)\n val userData: State get() = _userData\n\n fun updateName(\n newFirstName: String, newLastName: String\n ) {\n _userData.updateCopy {\n inside(UserData.details.name) {\n Name.firstName set newFirstName\n Name.lastName set newLastName\n }\n }\n }\n}\n"})})]})}function u(e={}){const{wrapper:n}={...(0,a.a)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(d,{...e})}):d(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>o,a:()=>s});var r=t(67294);const a={},i=r.createContext(a);function s(e){const n=r.useContext(i);return r.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function o(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(a):e.components||a:s(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/38fcd5cd.c865672b.js b/assets/js/38fcd5cd.3b6b2183.js similarity index 76% rename from assets/js/38fcd5cd.c865672b.js rename to assets/js/38fcd5cd.3b6b2183.js index 8f6493cc..ded4734f 100644 --- a/assets/js/38fcd5cd.c865672b.js +++ b/assets/js/38fcd5cd.3b6b2183.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7200],{55158:a=>{a.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":46,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/4","page":4,"postsPerPage":8,"totalPages":6,"totalCount":46,"previousPage":"/community/blog/tags/articles/page/3","nextPage":"/community/blog/tags/articles/page/5","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7200],{55158:a=>{a.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":47,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/4","page":4,"postsPerPage":8,"totalPages":6,"totalCount":47,"previousPage":"/community/blog/tags/articles/page/3","nextPage":"/community/blog/tags/articles/page/5","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/3cf8b4e1.0d721a6f.js b/assets/js/3cf8b4e1.f7f057d7.js similarity index 82% rename from assets/js/3cf8b4e1.0d721a6f.js rename to assets/js/3cf8b4e1.f7f057d7.js index 606c88dd..be43cb54 100644 --- a/assets/js/3cf8b4e1.0d721a6f.js +++ b/assets/js/3cf8b4e1.f7f057d7.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[9775],{5936:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/11","page":11,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/10","nextPage":"/community/blog/page/12","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[9775],{5936:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/11","page":11,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/10","nextPage":"/community/blog/page/12","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/45742c5c.dc5436ea.js b/assets/js/45742c5c.804e16e5.js similarity index 73% rename from assets/js/45742c5c.dc5436ea.js rename to assets/js/45742c5c.804e16e5.js index 969f4efc..202964a0 100644 --- a/assets/js/45742c5c.dc5436ea.js +++ b/assets/js/45742c5c.804e16e5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[374],{50996:t=>{t.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":46,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles","page":1,"postsPerPage":8,"totalPages":6,"totalCount":46,"nextPage":"/community/blog/tags/articles/page/2","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[374],{50996:t=>{t.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":47,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles","page":1,"postsPerPage":8,"totalPages":6,"totalCount":47,"nextPage":"/community/blog/tags/articles/page/2","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/51994487.2afce5bb.js b/assets/js/51994487.82ad4f74.js similarity index 82% rename from assets/js/51994487.2afce5bb.js rename to assets/js/51994487.82ad4f74.js index 4a2db7c1..fc253a55 100644 --- a/assets/js/51994487.2afce5bb.js +++ b/assets/js/51994487.82ad4f74.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7218],{48413:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/7","page":7,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/6","nextPage":"/community/blog/page/8","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7218],{48413:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/7","page":7,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/6","nextPage":"/community/blog/page/8","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/51a052e4.5d3c1cf9.js b/assets/js/51a052e4.8191dfb1.js similarity index 82% rename from assets/js/51a052e4.5d3c1cf9.js rename to assets/js/51a052e4.8191dfb1.js index 82555098..c606b7b5 100644 --- a/assets/js/51a052e4.5d3c1cf9.js +++ b/assets/js/51a052e4.8191dfb1.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7514],{46812:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/12","page":12,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/11","nextPage":"/community/blog/page/13","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7514],{46812:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/12","page":12,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/11","nextPage":"/community/blog/page/13","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/68297767.90349ea8.js b/assets/js/68297767.015f284c.js similarity index 82% rename from assets/js/68297767.90349ea8.js rename to assets/js/68297767.015f284c.js index 7f6278ff..5d7a6a07 100644 --- a/assets/js/68297767.90349ea8.js +++ b/assets/js/68297767.015f284c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3005],{74276:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/9","page":9,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/8","nextPage":"/community/blog/page/10","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3005],{74276:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/9","page":9,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/8","nextPage":"/community/blog/page/10","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/6d31d159.0fb7de4a.js b/assets/js/6d31d159.0fb7de4a.js new file mode 100644 index 00000000..349ac2cf --- /dev/null +++ b/assets/js/6d31d159.0fb7de4a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7453],{3646:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var a=n(85893),r=n(11151);const o={title:"Arrow Open Space @ Lambda World",category:"articles",tags:["articles","community"],image:"https://pub-c7459893ae854bbdb5ad00855f44c0c8.r2.dev/LandingPage_Lambda/Lambda_Logo_Blue.svg"},i="Arrow Open Space @ Lambda World",s={permalink:"/community/blog/2024/10/03/arrow-open-space",editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-10-03-arrow-open-space.md",source:"@site/content/blog/2024-10-03-arrow-open-space.md",title:"Arrow Open Space @ Lambda World",description:"The first Arrow & Fuctional Kotlin Open Space is taking place as part of Lambda World! This post contains the preliminary schedule, and shall be updated after the Open Space takes place with additional material, slides, and videos.",date:"2024-10-03T00:00:00.000Z",tags:[{label:"articles",permalink:"/community/blog/tags/articles"},{label:"community",permalink:"/community/blog/tags/community"}],readingTime:1.875,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Arrow Open Space @ Lambda World",category:"articles",tags:["articles","community"],image:"https://pub-c7459893ae854bbdb5ad00855f44c0c8.r2.dev/LandingPage_Lambda/Lambda_Logo_Blue.svg"},unlisted:!1,nextItem:{title:"Arrow plug-in for IntelliJ 0.1 is here!",permalink:"/community/blog/2024/06/01/intellij-plugin"}},l={authorsImageUrls:[]},c=[{value:"Unconference",id:"unconference",level:2},{value:"Build together",id:"build-together",level:2}];function d(e){const t={a:"a",em:"em",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(t.p,{children:["The first ",(0,a.jsx)(t.a,{href:"https://www.lambda.world/workshops/Arrow%20%26%20Functional%20Kotlin%20Open%20Space/",children:"Arrow & Fuctional Kotlin Open Space"})," is taking place as part of ",(0,a.jsx)(t.a,{href:"https://lambda.world",children:"Lambda World"}),"! This post contains the preliminary schedule, and shall be updated after the Open Space takes place with additional material, slides, and videos."]}),"\n",(0,a.jsxs)("table",{children:[(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:"14.30 - 15.00"}),(0,a.jsxs)("td",{children:[(0,a.jsx)("i",{children:"Introduction to Arrow libraries"})," by ",(0,a.jsx)("a",{href:"https://nomisrev.github.io/",children:"Simon Vergauwen"})]})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:"15.00 - 16.30"}),(0,a.jsxs)("td",{children:[(0,a.jsx)("a",{href:"#unconference",children:(0,a.jsx)("i",{children:"Unconference"})})," and ",(0,a.jsx)("a",{href:"#build-together",children:(0,a.jsx)("i",{children:"Build together"})})," (in parallel, see below)"]})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:"16.30 - 16.50"}),(0,a.jsx)("td",{children:(0,a.jsx)("i",{children:"Closing remarks"})})]})]}),"\n",(0,a.jsx)(t.h2,{id:"unconference",children:"Unconference"}),"\n",(0,a.jsx)(t.p,{children:"We have a nice room, some sweets, and a nice projector. The perfect setup to share some knowledge about Arrow and Functional Kotlin! Our goal with the Unconference is to bring together people who can talk about something and people who want to learn about something."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.em,{children:"How does it work?"})," Please talk to one of the people in charge so they can change the spreadsheet."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["If you want to learn about a topic...","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["If the topic is not yet in the spreadsheet, add it in the first column with the ",(0,a.jsx)(t.em,{children:"Requested"})," status."]}),"\n",(0,a.jsx)(t.li,{children:"If the topic is in the spreadsheet, contact the potential speaker."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["If you want to talk about a topic...","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"If it is already in the spreadsheet, shout it out loud and let the talk begin!"}),"\n",(0,a.jsxs)(t.li,{children:["If not, add your topic and name with the ",(0,a.jsx)(t.em,{children:"Waiting"})," status, and wait for somebody to request it."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["Once the talk begins, change it status to ",(0,a.jsx)(t.em,{children:"In progress"}),", and once it is finished, move it to ",(0,a.jsx)(t.em,{children:"Done"}),".","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"It would be great if any material or code would be shared with the organizers, so we can later add it to this page."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)("iframe",{width:"100%",height:"300px",src:"https://docs.google.com/spreadsheets/d/15H8lXScJkX4aao02VqLcDqXwASlo-XrCvmlPl9qgN_Y/pubhtml?range=A1:C20&gid=0&single=true&widget=false&headers=false"}),"\n",(0,a.jsx)(t.h2,{id:"build-together",children:"Build together"}),"\n",(0,a.jsx)(t.p,{children:"The goal of the Open Space is to learn. Many of us around are happy to help, so feel free to work in any project you want, and explore ways to use more functional features in your Kotlin. Once again, don't be shy to ask :)"}),"\n",(0,a.jsx)(t.p,{children:"If you are not sure about where to start, we have prepared a few tutorials and projects for you."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://serranofp.com/poke-fun/",children:"Pok\xe9-Fun with Kotlin and Arrow"}),": exercises about different parts of Arrow, and how you can apply them to a Compose Multiplatform project."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://arrow-kt.io/learn/design/projects/",children:"Example projects"})," from the Arrow documentation"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},11151:(e,t,n)=>{n.d(t,{Z:()=>s,a:()=>i});var a=n(67294);const r={},o=a.createContext(r);function i(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/71429cd6.a88bd38c.js b/assets/js/71429cd6.4c9417e5.js similarity index 82% rename from assets/js/71429cd6.a88bd38c.js rename to assets/js/71429cd6.4c9417e5.js index 1e3ced41..aa5b45b3 100644 --- a/assets/js/71429cd6.a88bd38c.js +++ b/assets/js/71429cd6.4c9417e5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7926],{7225:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/5","page":5,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/4","nextPage":"/community/blog/page/6","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[7926],{7225:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/5","page":5,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/4","nextPage":"/community/blog/page/6","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/715bbc75.52d30aeb.js b/assets/js/715bbc75.52d30aeb.js deleted file mode 100644 index 5996d862..00000000 --- a/assets/js/715bbc75.52d30aeb.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3637],{97924:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var t=r(85893),i=r(11151);const o={title:"Arrow plug-in for IntelliJ 0.1 is here!",category:"articles",tags:["intellij","articles"]},s="Arrow plug-in for IntelliJ 0.1 is here!",l={permalink:"/community/blog/2024/06/01/intellij-plugin",editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-06-01-intellij-plugin.md",source:"@site/content/blog/2024-06-01-intellij-plugin.md",title:"Arrow plug-in for IntelliJ 0.1 is here!",description:"One of the main goals of the Arrow project is to produce libraries",date:"2024-06-01T00:00:00.000Z",tags:[{label:"intellij",permalink:"/community/blog/tags/intellij"},{label:"articles",permalink:"/community/blog/tags/articles"}],readingTime:1.41,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Arrow plug-in for IntelliJ 0.1 is here!",category:"articles",tags:["intellij","articles"]},unlisted:!1,nextItem:{title:"Arrow 1.2.3 release",permalink:"/community/blog/2024/02/28/arrow-1-2-3"}},a={authorsImageUrls:[]},c=[];function d(e){const n={a:"a",code:"code",p:"p",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["One of the main goals of the Arrow project is to produce libraries\nthat follow well-known Kotlin idioms, and we strive to make them\nas discoverable as possible. Nevertheless, the surface of some\ncomponents, like ",(0,t.jsx)(n.a,{href:"/learn/typed-errors/",children:"typed errors"}),",\nis quite large.\nFor that reason, we have been busy in the last weeks preparing\nthe first release of the\n",(0,t.jsx)(n.a,{href:"https://plugins.jetbrains.com/plugin/24550-arrow",children:"Arrow plug-in for IntelliJ-based IDEs"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["This first version already focuses on three different aspects of\nArrow usage where we found that an additional companion can make\na big difference. The first aspect is the usage of typed errors:\nthe IDE will now suggest missing ",(0,t.jsx)(n.code,{children:".bind()"})," or ",(0,t.jsx)(n.code,{children:".bindAll()"}),",\nmapping of error using ",(0,t.jsx)(n.code,{children:"withError"}),", and promoting idioms like\n",(0,t.jsx)(n.code,{children:"ensure"})," whenever possible."]}),"\n",(0,t.jsxs)(n.p,{children:["The second aspect is warning about wrong usages of Arrow APIs\nwhich cannot be prevented by Kotlin's type system alone. This includes\nescaping of ",(0,t.jsx)(n.code,{children:"Raise"})," contexts -- for example, using ",(0,t.jsx)(n.code,{children:"sequence"})," or\n",(0,t.jsx)(n.code,{children:"flow"})," inside ",(0,t.jsx)(n.code,{children:"either"})," --, using ",(0,t.jsx)(n.code,{children:"Atomic"})," with primitive types\n-- where ",(0,t.jsx)(n.code,{children:"AtomicInt"})," or ",(0,t.jsx)(n.code,{children:"AtomicBoolean"})," should be used instead --,\nor matching on ",(0,t.jsx)(n.code,{children:"Eval"})," instances directly instead of using the\nprovided API -- which can easily lead to broken invariants."]}),"\n",(0,t.jsxs)(n.p,{children:["The third aspect is applying some known recipes which may be hard\nto know upfront. The first release includes a suggestion to add\nthe corresponding ",(0,t.jsx)(n.a,{href:"/learn/quickstart/serialization/",children:"serializer"}),"\nwhen a type marked as ",(0,t.jsx)(n.code,{children:"@Serializable"})," includes an Arrow Core type.\nThis is an area which we would like to explore more, helping with\nthe difficulties raised by the community."]}),"\n",(0,t.jsxs)(n.p,{children:["The plug-in lives in a ",(0,t.jsx)(n.a,{href:"https://github.com/arrow-kt/arrow-intellij",children:"separate repository"}),".\nPlease let us know your experience, and don't be shy to open issues\nwith suggestions for more features. They would help not only you\nbut potentially every user of the Arrow library."]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>s});var t=r(67294);const i={},o=t.createContext(i);function s(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/715bbc75.7979c638.js b/assets/js/715bbc75.7979c638.js new file mode 100644 index 00000000..55005738 --- /dev/null +++ b/assets/js/715bbc75.7979c638.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[3637],{97924:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var t=r(85893),i=r(11151);const o={title:"Arrow plug-in for IntelliJ 0.1 is here!",category:"articles",tags:["intellij","articles"]},s="Arrow plug-in for IntelliJ 0.1 is here!",l={permalink:"/community/blog/2024/06/01/intellij-plugin",editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-06-01-intellij-plugin.md",source:"@site/content/blog/2024-06-01-intellij-plugin.md",title:"Arrow plug-in for IntelliJ 0.1 is here!",description:"One of the main goals of the Arrow project is to produce libraries",date:"2024-06-01T00:00:00.000Z",tags:[{label:"intellij",permalink:"/community/blog/tags/intellij"},{label:"articles",permalink:"/community/blog/tags/articles"}],readingTime:1.41,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Arrow plug-in for IntelliJ 0.1 is here!",category:"articles",tags:["intellij","articles"]},unlisted:!1,prevItem:{title:"Arrow Open Space @ Lambda World",permalink:"/community/blog/2024/10/03/arrow-open-space"},nextItem:{title:"Arrow 1.2.3 release",permalink:"/community/blog/2024/02/28/arrow-1-2-3"}},a={authorsImageUrls:[]},c=[];function d(e){const n={a:"a",code:"code",p:"p",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["One of the main goals of the Arrow project is to produce libraries\nthat follow well-known Kotlin idioms, and we strive to make them\nas discoverable as possible. Nevertheless, the surface of some\ncomponents, like ",(0,t.jsx)(n.a,{href:"/learn/typed-errors/",children:"typed errors"}),",\nis quite large.\nFor that reason, we have been busy in the last weeks preparing\nthe first release of the\n",(0,t.jsx)(n.a,{href:"https://plugins.jetbrains.com/plugin/24550-arrow",children:"Arrow plug-in for IntelliJ-based IDEs"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["This first version already focuses on three different aspects of\nArrow usage where we found that an additional companion can make\na big difference. The first aspect is the usage of typed errors:\nthe IDE will now suggest missing ",(0,t.jsx)(n.code,{children:".bind()"})," or ",(0,t.jsx)(n.code,{children:".bindAll()"}),",\nmapping of error using ",(0,t.jsx)(n.code,{children:"withError"}),", and promoting idioms like\n",(0,t.jsx)(n.code,{children:"ensure"})," whenever possible."]}),"\n",(0,t.jsxs)(n.p,{children:["The second aspect is warning about wrong usages of Arrow APIs\nwhich cannot be prevented by Kotlin's type system alone. This includes\nescaping of ",(0,t.jsx)(n.code,{children:"Raise"})," contexts -- for example, using ",(0,t.jsx)(n.code,{children:"sequence"})," or\n",(0,t.jsx)(n.code,{children:"flow"})," inside ",(0,t.jsx)(n.code,{children:"either"})," --, using ",(0,t.jsx)(n.code,{children:"Atomic"})," with primitive types\n-- where ",(0,t.jsx)(n.code,{children:"AtomicInt"})," or ",(0,t.jsx)(n.code,{children:"AtomicBoolean"})," should be used instead --,\nor matching on ",(0,t.jsx)(n.code,{children:"Eval"})," instances directly instead of using the\nprovided API -- which can easily lead to broken invariants."]}),"\n",(0,t.jsxs)(n.p,{children:["The third aspect is applying some known recipes which may be hard\nto know upfront. The first release includes a suggestion to add\nthe corresponding ",(0,t.jsx)(n.a,{href:"/learn/quickstart/serialization/",children:"serializer"}),"\nwhen a type marked as ",(0,t.jsx)(n.code,{children:"@Serializable"})," includes an Arrow Core type.\nThis is an area which we would like to explore more, helping with\nthe difficulties raised by the community."]}),"\n",(0,t.jsxs)(n.p,{children:["The plug-in lives in a ",(0,t.jsx)(n.a,{href:"https://github.com/arrow-kt/arrow-intellij",children:"separate repository"}),".\nPlease let us know your experience, and don't be shy to open issues\nwith suggestions for more features. They would help not only you\nbut potentially every user of the Arrow library."]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>s});var t=r(67294);const i={},o=t.createContext(i);function s(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7438dad1.3f047ae6.js b/assets/js/7438dad1.3f047ae6.js new file mode 100644 index 00000000..b1d8bfe1 --- /dev/null +++ b/assets/js/7438dad1.3f047ae6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[4064],{43243:(e,t,n)=>{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var a=n(85893),r=n(11151);const o={title:"Arrow Open Space @ Lambda World",category:"articles",tags:["articles","community"],image:"https://pub-c7459893ae854bbdb5ad00855f44c0c8.r2.dev/LandingPage_Lambda/Lambda_Logo_Blue.svg"},i="Arrow Open Space @ Lambda World",s={permalink:"/community/blog/2024/10/03/arrow-open-space",editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-10-03-arrow-open-space.md",source:"@site/content/blog/2024-10-03-arrow-open-space.md",title:"Arrow Open Space @ Lambda World",description:"The first Arrow & Fuctional Kotlin Open Space is taking place as part of Lambda World! This post contains the preliminary schedule, and shall be updated after the Open Space takes place with additional material, slides, and videos.",date:"2024-10-03T00:00:00.000Z",tags:[{label:"articles",permalink:"/community/blog/tags/articles"},{label:"community",permalink:"/community/blog/tags/community"}],readingTime:1.875,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Arrow Open Space @ Lambda World",category:"articles",tags:["articles","community"],image:"https://pub-c7459893ae854bbdb5ad00855f44c0c8.r2.dev/LandingPage_Lambda/Lambda_Logo_Blue.svg"},unlisted:!1,nextItem:{title:"Arrow plug-in for IntelliJ 0.1 is here!",permalink:"/community/blog/2024/06/01/intellij-plugin"}},l={authorsImageUrls:[]},c=[{value:"Unconference",id:"unconference",level:2},{value:"Build together",id:"build-together",level:2}];function d(e){const t={a:"a",em:"em",h2:"h2",li:"li",p:"p",ul:"ul",...(0,r.a)(),...e.components};return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)(t.p,{children:["The first ",(0,a.jsx)(t.a,{href:"https://www.lambda.world/workshops/Arrow%20%26%20Functional%20Kotlin%20Open%20Space/",children:"Arrow & Fuctional Kotlin Open Space"})," is taking place as part of ",(0,a.jsx)(t.a,{href:"https://lambda.world",children:"Lambda World"}),"! This post contains the preliminary schedule, and shall be updated after the Open Space takes place with additional material, slides, and videos."]}),"\n",(0,a.jsxs)("table",{children:[(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:"14.30 - 15.00"}),(0,a.jsxs)("td",{children:[(0,a.jsx)("i",{children:"Introduction to Arrow libraries"})," by ",(0,a.jsx)("a",{href:"https://nomisrev.github.io/",children:"Simon Vergauwen"})]})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:"15.00 - 16.30"}),(0,a.jsxs)("td",{children:[(0,a.jsx)("a",{href:"#unconference",children:(0,a.jsx)("i",{children:"Unconference"})})," and ",(0,a.jsx)("a",{href:"#build-together",children:(0,a.jsx)("i",{children:"Build together"})})," (in parallel, see below)"]})]}),(0,a.jsxs)("tr",{children:[(0,a.jsx)("td",{children:"16.30 - 16.50"}),(0,a.jsx)("td",{children:(0,a.jsx)("i",{children:"Closing remarks"})})]})]}),"\n",(0,a.jsx)(t.h2,{id:"unconference",children:"Unconference"}),"\n",(0,a.jsx)(t.p,{children:"We have a nice room, some sweets, and a nice projector. The perfect setup to share some knowledge about Arrow and Functional Kotlin! Our goal with the Unconference is to bring together people who can talk about something and people who want to learn about something."}),"\n",(0,a.jsxs)(t.p,{children:[(0,a.jsx)(t.em,{children:"How does it work?"})," Please talk to one of the people in charge so they can change the spreadsheet."]}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["If you want to learn about a topic...","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:["If the topic is not yet in the spreadsheet, add it in the first column with the ",(0,a.jsx)(t.em,{children:"Requested"})," status."]}),"\n",(0,a.jsx)(t.li,{children:"If the topic is in the spreadsheet, contact the potential speaker."}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["If you want to talk about a topic...","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"If it is already in the spreadsheet, shout it out loud and let the talk begin!"}),"\n",(0,a.jsxs)(t.li,{children:["If not, add your topic and name with the ",(0,a.jsx)(t.em,{children:"Waiting"})," status, and wait for somebody to request it."]}),"\n"]}),"\n"]}),"\n",(0,a.jsxs)(t.li,{children:["Once the talk begins, change it status to ",(0,a.jsx)(t.em,{children:"In progress"}),", and once it is finished, move it to ",(0,a.jsx)(t.em,{children:"Done"}),".","\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsx)(t.li,{children:"It would be great if any material or code would be shared with the organizers, so we can later add it to this page."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,a.jsx)("iframe",{width:"100%",height:"300px",src:"https://docs.google.com/spreadsheets/d/15H8lXScJkX4aao02VqLcDqXwASlo-XrCvmlPl9qgN_Y/pubhtml?range=A1:C20&gid=0&single=true&widget=false&headers=false"}),"\n",(0,a.jsx)(t.h2,{id:"build-together",children:"Build together"}),"\n",(0,a.jsx)(t.p,{children:"The goal of the Open Space is to learn. Many of us around are happy to help, so feel free to work in any project you want, and explore ways to use more functional features in your Kotlin. Once again, don't be shy to ask :)"}),"\n",(0,a.jsx)(t.p,{children:"If you are not sure about where to start, we have prepared a few tutorials and projects for you."}),"\n",(0,a.jsxs)(t.ul,{children:["\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://serranofp.com/poke-fun/",children:"Pok\xe9-Fun with Kotlin and Arrow"}),": exercises about different parts of Arrow, and how you can apply them to a Compose Multiplatform project."]}),"\n",(0,a.jsxs)(t.li,{children:[(0,a.jsx)(t.a,{href:"https://arrow-kt.io/learn/design/projects/",children:"Example projects"})," from the Arrow documentation"]}),"\n"]})]})}function h(e={}){const{wrapper:t}={...(0,r.a)(),...e.components};return t?(0,a.jsx)(t,{...e,children:(0,a.jsx)(d,{...e})}):d(e)}},11151:(e,t,n)=>{n.d(t,{Z:()=>s,a:()=>i});var a=n(67294);const r={},o=a.createContext(r);function i(e){const t=a.useContext(o);return a.useMemo((function(){return"function"==typeof e?e(t):{...t,...e}}),[t,e])}function s(e){let t;return t=e.disableParentContext?"function"==typeof e.components?e.components(r):e.components||r:i(e.components),a.createElement(o.Provider,{value:t},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/7d60642f.738e5e97.js b/assets/js/7d60642f.738e5e97.js new file mode 100644 index 00000000..d67e3c61 --- /dev/null +++ b/assets/js/7d60642f.738e5e97.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[8108],{54735:l=>{l.exports=JSON.parse('{"tags":[{"label":"articles","permalink":"/community/blog/tags/articles","count":47},{"label":"community","permalink":"/community/blog/tags/community","count":1},{"label":"intellij","permalink":"/community/blog/tags/intellij","count":1},{"label":"core","permalink":"/community/blog/tags/core","count":80},{"label":"videos","permalink":"/community/blog/tags/videos","count":49},{"label":"optics","permalink":"/community/blog/tags/optics","count":6},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks","count":4},{"label":"meta","permalink":"/community/blog/tags/meta","count":10},{"label":"analysis","permalink":"/community/blog/tags/analysis","count":2},{"label":"fx","permalink":"/community/blog/tags/fx","count":25},{"label":"tutorials","permalink":"/community/blog/tags/tutorials","count":4},{"label":"incubator","permalink":"/community/blog/tags/incubator","count":2},{"label":"mtl","permalink":"/community/blog/tags/mtl","count":1}]}')}}]); \ No newline at end of file diff --git a/assets/js/7d60642f.ca2f66a9.js b/assets/js/7d60642f.ca2f66a9.js deleted file mode 100644 index d99aeb41..00000000 --- a/assets/js/7d60642f.ca2f66a9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[8108],{54735:l=>{l.exports=JSON.parse('{"tags":[{"label":"intellij","permalink":"/community/blog/tags/intellij","count":1},{"label":"articles","permalink":"/community/blog/tags/articles","count":46},{"label":"core","permalink":"/community/blog/tags/core","count":80},{"label":"videos","permalink":"/community/blog/tags/videos","count":49},{"label":"optics","permalink":"/community/blog/tags/optics","count":6},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks","count":4},{"label":"meta","permalink":"/community/blog/tags/meta","count":10},{"label":"analysis","permalink":"/community/blog/tags/analysis","count":2},{"label":"fx","permalink":"/community/blog/tags/fx","count":25},{"label":"tutorials","permalink":"/community/blog/tags/tutorials","count":4},{"label":"incubator","permalink":"/community/blog/tags/incubator","count":2},{"label":"mtl","permalink":"/community/blog/tags/mtl","count":1}]}')}}]); \ No newline at end of file diff --git a/assets/js/8208b5e1.0fbd4203.js b/assets/js/8208b5e1.0fbd4203.js new file mode 100644 index 00000000..1a385258 --- /dev/null +++ b/assets/js/8208b5e1.0fbd4203.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[392],{1128:t=>{t.exports=JSON.parse('{"tag":{"label":"community","permalink":"/community/blog/tags/community","allTagsPath":"/community/blog/tags","count":1,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/community","page":1,"postsPerPage":8,"totalPages":1,"totalCount":1,"blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/82f29da8.2cb76b99.js b/assets/js/82f29da8.23664c97.js similarity index 80% rename from assets/js/82f29da8.2cb76b99.js rename to assets/js/82f29da8.23664c97.js index 527c3799..225a4007 100644 --- a/assets/js/82f29da8.2cb76b99.js +++ b/assets/js/82f29da8.23664c97.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[1199],{41658:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/14","page":14,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/13","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[1199],{41658:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/14","page":14,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/13","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/8e06aed5.fc137880.js b/assets/js/8e06aed5.182ab55f.js similarity index 51% rename from assets/js/8e06aed5.fc137880.js rename to assets/js/8e06aed5.182ab55f.js index 83b44e06..477c24f4 100644 --- a/assets/js/8e06aed5.fc137880.js +++ b/assets/js/8e06aed5.182ab55f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[8104],{53627:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var o=t(85893),i=t(11151);const r={id:"validation",title:"Validation",description:"Worked out example of validation.",sidebar_position:4},a="Validation",s={id:"learn/typed-errors/validation",title:"Validation",description:"Worked out example of validation.",source:"@site/content/docs/learn/typed-errors/validation.md",sourceDirName:"learn/typed-errors",slug:"/learn/typed-errors/validation",permalink:"/learn/typed-errors/validation",draft:!1,unlisted:!1,editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/docs/learn/typed-errors/validation.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{id:"validation",title:"Validation",description:"Worked out example of validation.",sidebar_position:4},sidebar:"learnSidebar",previous:{title:"Either & Ior",permalink:"/learn/typed-errors/either-and-ior"},next:{title:"From Either to Raise",permalink:"/learn/typed-errors/from-either-to-raise"}},l={},c=[{value:"Smart constructors",id:"smart-constructors",level:2},{value:"Fail-first vs. accumulation",id:"fail-first-vs-accumulation",level:2},{value:"Validating a list",id:"validating-a-list",level:2},{value:"Variants of map + accumulation",id:"variants-of-map--accumulation",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"validation",children:"Validation"}),"\n",(0,o.jsx)(n.p,{children:"This tutorial shows a concrete example of using typed errors to implement\ndomain validation. In particular, we begin with the following domain:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Author(val name: String)\ndata class Book(val title: String, val authors: NonEmptyList)\n"})}),"\n",(0,o.jsx)(n.p,{children:"over which we want to implement the following rules:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"The given title should not be empty,"}),"\n",(0,o.jsxs)(n.li,{children:["The list of authors should ",(0,o.jsx)(n.a,{href:"../../collections-functions/non-empty/",children:"not be empty"}),","]}),"\n",(0,o.jsx)(n.li,{children:"None of the author names should be empty."}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"We want to accumulate as many error as possible."}),"\n",(0,o.jsx)(n.h2,{id:"smart-constructors",children:"Smart constructors"}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"Author"})," class exposes its constructor, so we cannot prevent from creating\nwrong values. One could introduce a ",(0,o.jsx)(n.code,{children:"require"})," in the constructor, but we prefer\nto use the typed error mechanism instead. A common pattern in this case is to\n",(0,o.jsx)(n.em,{children:"hide"})," the constructor, and provide a ",(0,o.jsx)(n.em,{children:"smart constructor"})," by adding an ",(0,o.jsx)(n.code,{children:"invoke"}),"\noperator in the companion."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"object EmptyAuthorName\n\ndata class Author private constructor(val name: String) {\n companion object {\n operator fun invoke(name: String): Either = TODO()\n }\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This way the users of this class still use ",(0,o.jsx)(n.code,{children:'Author("me")'})," to create a new name,\nin the same way one would use a constructor, but actually our ",(0,o.jsx)(n.code,{children:"invoke"})," function\nis called. This allows us to refine the type to an ",(0,o.jsx)(n.code,{children:"Either"}),", which can return\nan error. The implementation uses the ",(0,o.jsx)(n.code,{children:"either"})," computation block, with ",(0,o.jsx)(n.code,{children:"ensure"}),"\ndescribing the constraint #3."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Author private constructor(val name: String) {\n companion object {\n operator fun invoke(name: String): Either = either {\n ensure(name.isNotEmpty()) { EmptyAuthorName }\n Author(name)\n }\n }\n}\n"})}),"\n",(0,o.jsx)(n.h2,{id:"fail-first-vs-accumulation",children:"Fail-first vs. accumulation"}),"\n",(0,o.jsxs)(n.p,{children:["We are going to use a similar approach for ",(0,o.jsx)(n.code,{children:"Book"}),", introducing a smart\nconstructor. We have several different errors, though, which we define as\na hierarchy. Note that ",(0,o.jsx)(n.code,{children:"EmptyAuthor"})," is a different type than before,\nsince we want to accommodate the index of the author."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"sealed interface BookValidationError\nobject EmptyTitle: BookValidationError\nobject NoAuthors: BookValidationError\ndata class EmptyAuthor(val index: Int): BookValidationError\n\ndata class Book private constructor(\n val title: String, val authors: NonEmptyList\n) {\n companion object {\n operator fun invoke(\n title: String, authors: Iterable\n ): Either = TODO()\n }\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Let's forget about validating each author for a moment, and just implement the\nemptiness checks for the title and the authors list. Note that in the latter\ncase we perform both the check and the conversion to ",(0,o.jsx)(n.code,{children:"NonEmptyList"})," in a single\ngo using ",(0,o.jsx)(n.code,{children:"ensureNotNull"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Book private constructor(\n val title: String, val authors: NonEmptyList\n) {\n companion object {\n operator fun invoke(\n title: String, authors: Iterable\n ): Either = either {\n ensure(title.isNotEmpty()) { EmptyTitle }\n ensureNotNull(authors.toNonEmptyListOrNull()) { NoAuthors }\n Book(title, TODO())\n }\n }\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This code has a problem, though: it only returns ",(0,o.jsx)(n.em,{children:"one"})," error, even if there are\ntwo problems with the data of the ",(0,o.jsx)(n.code,{children:"Book"}),". We would rather use an ",(0,o.jsx)(n.em,{children:"accumulation"}),"\napproach, so we can give back as much information as possible to the user.\nThis requires two changes to the code:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The result type is now a ",(0,o.jsx)(n.code,{children:"NonEmptyList"})," of problems,"]}),"\n",(0,o.jsxs)(n.li,{children:["We need to wrap the different validations in ",(0,o.jsx)(n.code,{children:"zipOrAccumulate"}),"."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Book private constructor(\n val title: String, val authors: NonEmptyList\n) {\n companion object {\n operator fun invoke(\n title: String, authors: Iterable\n ): Either, Book> = either {\n zipOrAccumulate(\n { ensure(title.isNotEmpty()) { EmptyTitle } },\n { ensureNotNull(authors.toNonEmptyListOrNull()) { NoAuthors } }\n ) { _, _ ->\n Book(title, TODO())\n }\n }\n }\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The result of each of the arguments of ",(0,o.jsx)(n.code,{children:"zipOrAccumulate"})," are available in the\ntrailing lambda. In this case we are not using them: we have the ",(0,o.jsx)(n.code,{children:"title"}),"\nalready available, and for the list of authors we still need to perform the\nconversion from ",(0,o.jsx)(n.code,{children:"String"})," to ",(0,o.jsx)(n.code,{children:"Author"}),"."]}),"\n",(0,o.jsx)(n.admonition,{title:"Arguments to zipOrAccumulate",type:"tip",children:(0,o.jsxs)(n.p,{children:["All but the last argument to ",(0,o.jsx)(n.code,{children:"zipOrAccumulate"})," represent the different\nvalidations we want to run aggregating their output. Those arguments are\noften ",(0,o.jsx)(n.em,{children:"blocks"})," wrapped in ",(0,o.jsx)(n.code,{children:"{"})," curly braces ",(0,o.jsx)(n.code,{children:"}"}),", which is a bit unusual for\nmost Kotliners."]})}),"\n",(0,o.jsx)(n.h2,{id:"validating-a-list",children:"Validating a list"}),"\n",(0,o.jsxs)(n.p,{children:["The next step is turning the given ",(0,o.jsx)(n.code,{children:"authors"}),", which is a list of ",(0,o.jsx)(n.code,{children:"String"}),"s, into\na list of ",(0,o.jsx)(n.code,{children:"Author"}),"s. We need to run the smart constructor, thus, but at the same\ntime we should accumulate any potential problems. Since this is related to\nauthor checks, we'll include this as part of the second validation."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Book private constructor(\n val title: String, val authors: NonEmptyList\n) {\n companion object {\n operator fun invoke(\n title: String, authors: Iterable\n ): Either, Book> = either {\n zipOrAccumulate(\n { ensure(title.isNotEmpty()) { EmptyTitle } },\n { \n val validatedAuthors = mapOrAccumulate(authors.withIndex()) { nameAndIx ->\n Author(nameAndIx.value)\n .recover { _ -> raise(EmptyAuthor(nameAndIx.index)) }\n .bind()\n }\n ensureNotNull(validatedAuthors.toNonEmptyListOrNull()) { NoAuthors }\n }\n ) { _, authorsNel ->\n Book(title, authorsNel)\n }\n }\n }\n}\n"})}),"\n",(0,o.jsx)(n.p,{children:"This additional check is quite complex, so let's unravel it step by step:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["We use ",(0,o.jsx)(n.code,{children:"authors.withIndex()"})," to create an iterable containing the values\nin conjunction with the index they live in, this is necessary to create\nthe right ",(0,o.jsx)(n.code,{children:"EmptyAuthor"})," error value."]}),"\n",(0,o.jsxs)(n.li,{children:["With ",(0,o.jsx)(n.code,{children:"mapOrAccumulate"})," we state that we want to perform some validation over\na collection of elements, accumulating each possible error."]}),"\n",(0,o.jsxs)(n.li,{children:["The call to ",(0,o.jsx)(n.code,{children:"Author(it.value)"})," return an ",(0,o.jsx)(n.code,{children:"Either"})," with the wrong error type\n(",(0,o.jsx)(n.code,{children:"EmptyAuthorName"})," instead of ",(0,o.jsx)(n.code,{children:"EmptyAuthor"}),"). To transform this value we\nuse the ",(0,o.jsx)(n.code,{children:"recover"})," extension function."]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{title:"Recover vs. Map Left",type:"tip",children:(0,o.jsxs)(n.p,{children:["Another possibility would be to use ",(0,o.jsx)(n.code,{children:"mapLeft { EmptyAuthor(it.index) }"}),".\nThe difference between ",(0,o.jsx)(n.code,{children:"recover"})," and ",(0,o.jsx)(n.code,{children:"mapLeft"})," is that the latter only transforms\nthe error value, whereas in the former you can use any typed error computation."]})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Finally, we use ",(0,o.jsx)(n.code,{children:".bind()"})," to embed the ",(0,o.jsx)(n.code,{children:"Either"})," into the computation block.\nEssentially, every time you are using a value of type ",(0,o.jsx)(n.code,{children:"Either"})," inside an\n",(0,o.jsx)(n.code,{children:"either"})," (or any other ",(0,o.jsx)(n.code,{children:"Raise"})," block), such a call is required."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["The result of the mapping is a ",(0,o.jsx)(n.code,{children:"List"}),", that we can now use to create the\nfinal ",(0,o.jsx)(n.code,{children:"Book"}),". This value is available in the last lambda of ",(0,o.jsx)(n.code,{children:"zipOrAccumulate"}),",\nthat we've called ",(0,o.jsx)(n.code,{children:"validatedAuthors"})," in the code above."]}),"\n",(0,o.jsx)(n.h3,{id:"variants-of-map--accumulation",children:"Variants of map + accumulation"}),"\n",(0,o.jsx)(n.p,{children:"In the code above there's one section which can be written in several different\nways, namely the mapping over a list while accumulating any errors raised\nduring the processing of each of the elements."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"val validatedAuthors = mapOrAccumulate(authors.withIndex()) { nameAndIx ->\n Author(nameAndIx.value)\n .mapLeft { EmptyAuthor(nameAndIx.index) }\n .bind()\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This first version uses the variant of ",(0,o.jsx)(n.code,{children:"mapOrAccumulate"})," which lives in\n",(0,o.jsx)(n.code,{children:"Raise"})," and takes the collection to work on as first argument. This variant\nprovides ",(0,o.jsx)(n.code,{children:"Raise"})," inside the block (hence the need to call ",(0,o.jsx)(n.code,{children:".bind()"}),"), and\n",(0,o.jsx)(n.code,{children:"raise"}),"s automatically if any error is found."]}),"\n",(0,o.jsxs)(n.p,{children:["Another way to write the code above is creating a list of ",(0,o.jsx)(n.code,{children:"Either"})," using\n",(0,o.jsx)(n.code,{children:"map"}),", and then using ",(0,o.jsx)(n.code,{children:".bindAll()"})," at the very end. This often turns into\nsimpler code when your validations use wrapper types, as we do here, since\nyou don't need to call the intermediate ",(0,o.jsx)(n.code,{children:".bind()"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"val validatedAuthors = authors.withIndex().map { nameAndIx ->\n Author(nameAndIx.value)\n .mapLeft { EmptyAuthor(nameAndIx.index) }\n}.bindAll()\n"})}),"\n",(0,o.jsx)(n.p,{children:"Any of these approaches are equivalent, given that the function that validates\neach of the elements doesn't perform any side effects."})]})}function d(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>s,a:()=>a});var o=t(67294);const i={},r=o.createContext(i);function a(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[8104],{53627:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var o=t(85893),i=t(11151);const r={id:"validation",title:"Validation",description:"Worked out example of validation.",sidebar_position:4},a="Validation",s={id:"learn/typed-errors/validation",title:"Validation",description:"Worked out example of validation.",source:"@site/content/docs/learn/typed-errors/validation.md",sourceDirName:"learn/typed-errors",slug:"/learn/typed-errors/validation",permalink:"/learn/typed-errors/validation",draft:!1,unlisted:!1,editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/docs/learn/typed-errors/validation.md",tags:[],version:"current",sidebarPosition:4,frontMatter:{id:"validation",title:"Validation",description:"Worked out example of validation.",sidebar_position:4},sidebar:"learnSidebar",previous:{title:"Either & Ior",permalink:"/learn/typed-errors/either-and-ior"},next:{title:"From Either to Raise",permalink:"/learn/typed-errors/from-either-to-raise"}},l={},c=[{value:"Smart constructors",id:"smart-constructors",level:2},{value:"Fail-first vs. accumulation",id:"fail-first-vs-accumulation",level:2},{value:"Validating a list",id:"validating-a-list",level:2},{value:"Variants of map + accumulation",id:"variants-of-map--accumulation",level:3}];function h(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h1:"h1",h2:"h2",h3:"h3",li:"li",ol:"ol",p:"p",pre:"pre",ul:"ul",...(0,i.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.h1,{id:"validation",children:"Validation"}),"\n",(0,o.jsx)(n.p,{children:"This tutorial shows a concrete example of using typed errors to implement\ndomain validation. In particular, we begin with the following domain:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Author(val name: String)\ndata class Book(val title: String, val authors: NonEmptyList)\n"})}),"\n",(0,o.jsx)(n.p,{children:"over which we want to implement the following rules:"}),"\n",(0,o.jsxs)(n.ol,{children:["\n",(0,o.jsx)(n.li,{children:"The given title should not be empty,"}),"\n",(0,o.jsxs)(n.li,{children:["The list of authors should ",(0,o.jsx)(n.a,{href:"../../collections-functions/non-empty/",children:"not be empty"}),","]}),"\n",(0,o.jsx)(n.li,{children:"None of the author names should be empty."}),"\n"]}),"\n",(0,o.jsx)(n.p,{children:"We want to accumulate as many error as possible."}),"\n",(0,o.jsx)(n.h2,{id:"smart-constructors",children:"Smart constructors"}),"\n",(0,o.jsxs)(n.p,{children:["The ",(0,o.jsx)(n.code,{children:"Author"})," class exposes its constructor, so we cannot prevent from creating\nwrong values. One could introduce a ",(0,o.jsx)(n.code,{children:"require"})," in the constructor, but we prefer\nto use the typed error mechanism instead. A common pattern in this case is to\n",(0,o.jsx)(n.em,{children:"hide"})," the constructor, and provide a ",(0,o.jsx)(n.em,{children:"smart constructor"})," by adding an ",(0,o.jsx)(n.code,{children:"invoke"}),"\noperator in the companion."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"object EmptyAuthorName\n\ndata class Author private constructor(val name: String) {\n companion object {\n operator fun invoke(name: String): Either = TODO()\n }\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This way the users of this class still use ",(0,o.jsx)(n.code,{children:'Author("me")'})," to create a new name,\nin the same way one would use a constructor, but actually our ",(0,o.jsx)(n.code,{children:"invoke"})," function\nis called. This allows us to refine the type to an ",(0,o.jsx)(n.code,{children:"Either"}),", which can return\nan error. The implementation uses the ",(0,o.jsx)(n.code,{children:"either"})," computation block, with ",(0,o.jsx)(n.code,{children:"ensure"}),"\ndescribing the constraint #3."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Author private constructor(val name: String) {\n companion object {\n operator fun invoke(name: String): Either = either {\n ensure(name.isNotEmpty()) { EmptyAuthorName }\n Author(name)\n }\n }\n}\n"})}),"\n",(0,o.jsx)(n.h2,{id:"fail-first-vs-accumulation",children:"Fail-first vs. accumulation"}),"\n",(0,o.jsxs)(n.p,{children:["We are going to use a similar approach for ",(0,o.jsx)(n.code,{children:"Book"}),", introducing a smart\nconstructor. We have several different errors, though, which we define as\na hierarchy. Note that ",(0,o.jsx)(n.code,{children:"EmptyAuthor"})," is a different type than before,\nsince we want to accommodate the index of the author."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"sealed interface BookValidationError\nobject EmptyTitle: BookValidationError\nobject NoAuthors: BookValidationError\ndata class EmptyAuthor(val index: Int): BookValidationError\n\ndata class Book private constructor(\n val title: String, val authors: NonEmptyList\n) {\n companion object {\n operator fun invoke(\n title: String, authors: Iterable\n ): Either = TODO()\n }\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["Let's forget about validating each author for a moment, and just implement the\nemptiness checks for the title and the authors list. Note that in the latter\ncase we perform both the check and the conversion to ",(0,o.jsx)(n.code,{children:"NonEmptyList"})," in a single\ngo using ",(0,o.jsx)(n.code,{children:"ensureNotNull"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Book private constructor(\n val title: String, val authors: NonEmptyList\n) {\n companion object {\n operator fun invoke(\n title: String, authors: Iterable\n ): Either = either {\n ensure(title.isNotEmpty()) { EmptyTitle }\n ensureNotNull(authors.toNonEmptyListOrNull()) { NoAuthors }\n Book(title, TODO())\n }\n }\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This code has a problem, though: it only returns ",(0,o.jsx)(n.em,{children:"one"})," error, even if there are\ntwo problems with the data of the ",(0,o.jsx)(n.code,{children:"Book"}),". We would rather use an ",(0,o.jsx)(n.em,{children:"accumulation"}),"\napproach, so we can give back as much information as possible to the user.\nThis requires two changes to the code:"]}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["The result type is now a ",(0,o.jsx)(n.code,{children:"NonEmptyList"})," of problems,"]}),"\n",(0,o.jsxs)(n.li,{children:["We need to wrap the different validations in ",(0,o.jsx)(n.code,{children:"zipOrAccumulate"}),"."]}),"\n"]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Book private constructor(\n val title: String, val authors: NonEmptyList\n) {\n companion object {\n operator fun invoke(\n title: String, authors: Iterable\n ): Either, Book> = either {\n zipOrAccumulate(\n { ensure(title.isNotEmpty()) { EmptyTitle } },\n { ensureNotNull(authors.toNonEmptyListOrNull()) { NoAuthors } }\n ) { _, _ ->\n Unit\n }\n Book(title, TODO())\n }\n }\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["The result of each of the arguments of ",(0,o.jsx)(n.code,{children:"zipOrAccumulate"})," are available in the\ntrailing lambda. In this case we are not using them: we have the ",(0,o.jsx)(n.code,{children:"title"}),"\nalready available, and for the list of authors we still need to perform the\nconversion from ",(0,o.jsx)(n.code,{children:"String"})," to ",(0,o.jsx)(n.code,{children:"Author"}),"."]}),"\n",(0,o.jsx)(n.admonition,{title:"Arguments to zipOrAccumulate",type:"tip",children:(0,o.jsxs)(n.p,{children:["All but the last argument to ",(0,o.jsx)(n.code,{children:"zipOrAccumulate"})," represent the different\nvalidations we want to run aggregating their output. Those arguments are\noften ",(0,o.jsx)(n.em,{children:"blocks"})," wrapped in ",(0,o.jsx)(n.code,{children:"{"})," curly braces ",(0,o.jsx)(n.code,{children:"}"}),", which is a bit unusual for\nmost Kotliners."]})}),"\n",(0,o.jsx)(n.h2,{id:"validating-a-list",children:"Validating a list"}),"\n",(0,o.jsxs)(n.p,{children:["The next step is turning the given ",(0,o.jsx)(n.code,{children:"authors"}),", which is a list of ",(0,o.jsx)(n.code,{children:"String"}),"s, into\na list of ",(0,o.jsx)(n.code,{children:"Author"}),"s. We need to run the smart constructor, thus, but at the same\ntime we should accumulate any potential problems. Since this is related to\nauthor checks, we'll include this as part of the second validation."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{className:"language-kotlin",children:"data class Book private constructor(\n val title: String, val authors: NonEmptyList\n) {\n companion object {\n operator fun invoke(\n title: String, authors: Iterable\n ): Either, Book> = either {\n zipOrAccumulate(\n { ensure(title.isNotEmpty()) { EmptyTitle } },\n { \n val validatedAuthors = mapOrAccumulate(authors.withIndex()) { nameAndIx ->\n Author(nameAndIx.value)\n .recover { _ -> raise(EmptyAuthor(nameAndIx.index)) }\n .bind()\n }\n ensureNotNull(validatedAuthors.toNonEmptyListOrNull()) { NoAuthors }\n }\n ) { _, authorsNel ->\n Book(title, authorsNel)\n }\n }\n }\n}\n"})}),"\n",(0,o.jsx)(n.p,{children:"This additional check is quite complex, so let's unravel it step by step:"}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["We use ",(0,o.jsx)(n.code,{children:"authors.withIndex()"})," to create an iterable containing the values\nin conjunction with the index they live in, this is necessary to create\nthe right ",(0,o.jsx)(n.code,{children:"EmptyAuthor"})," error value."]}),"\n",(0,o.jsxs)(n.li,{children:["With ",(0,o.jsx)(n.code,{children:"mapOrAccumulate"})," we state that we want to perform some validation over\na collection of elements, accumulating each possible error."]}),"\n",(0,o.jsxs)(n.li,{children:["The call to ",(0,o.jsx)(n.code,{children:"Author(it.value)"})," return an ",(0,o.jsx)(n.code,{children:"Either"})," with the wrong error type\n(",(0,o.jsx)(n.code,{children:"EmptyAuthorName"})," instead of ",(0,o.jsx)(n.code,{children:"EmptyAuthor"}),"). To transform this value we\nuse the ",(0,o.jsx)(n.code,{children:"recover"})," extension function."]}),"\n"]}),"\n",(0,o.jsx)(n.admonition,{title:"Recover vs. Map Left",type:"tip",children:(0,o.jsxs)(n.p,{children:["Another possibility would be to use ",(0,o.jsx)(n.code,{children:"mapLeft { EmptyAuthor(it.index) }"}),".\nThe difference between ",(0,o.jsx)(n.code,{children:"recover"})," and ",(0,o.jsx)(n.code,{children:"mapLeft"})," is that the latter only transforms\nthe error value, whereas in the former you can use any typed error computation."]})}),"\n",(0,o.jsxs)(n.ul,{children:["\n",(0,o.jsxs)(n.li,{children:["Finally, we use ",(0,o.jsx)(n.code,{children:".bind()"})," to embed the ",(0,o.jsx)(n.code,{children:"Either"})," into the computation block.\nEssentially, every time you are using a value of type ",(0,o.jsx)(n.code,{children:"Either"})," inside an\n",(0,o.jsx)(n.code,{children:"either"})," (or any other ",(0,o.jsx)(n.code,{children:"Raise"})," block), such a call is required."]}),"\n"]}),"\n",(0,o.jsxs)(n.p,{children:["The result of the mapping is a ",(0,o.jsx)(n.code,{children:"List"}),", that we can now use to create the\nfinal ",(0,o.jsx)(n.code,{children:"Book"}),". This value is available in the last lambda of ",(0,o.jsx)(n.code,{children:"zipOrAccumulate"}),",\nthat we've called ",(0,o.jsx)(n.code,{children:"validatedAuthors"})," in the code above."]}),"\n",(0,o.jsx)(n.h3,{id:"variants-of-map--accumulation",children:"Variants of map + accumulation"}),"\n",(0,o.jsx)(n.p,{children:"In the code above there's one section which can be written in several different\nways, namely the mapping over a list while accumulating any errors raised\nduring the processing of each of the elements."}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"val validatedAuthors = mapOrAccumulate(authors.withIndex()) { nameAndIx ->\n Author(nameAndIx.value)\n .mapLeft { EmptyAuthor(nameAndIx.index) }\n .bind()\n}\n"})}),"\n",(0,o.jsxs)(n.p,{children:["This first version uses the variant of ",(0,o.jsx)(n.code,{children:"mapOrAccumulate"})," which lives in\n",(0,o.jsx)(n.code,{children:"Raise"})," and takes the collection to work on as first argument. This variant\nprovides ",(0,o.jsx)(n.code,{children:"Raise"})," inside the block (hence the need to call ",(0,o.jsx)(n.code,{children:".bind()"}),"), and\n",(0,o.jsx)(n.code,{children:"raise"}),"s automatically if any error is found."]}),"\n",(0,o.jsxs)(n.p,{children:["Another way to write the code above is creating a list of ",(0,o.jsx)(n.code,{children:"Either"})," using\n",(0,o.jsx)(n.code,{children:"map"}),", and then using ",(0,o.jsx)(n.code,{children:".bindAll()"})," at the very end. This often turns into\nsimpler code when your validations use wrapper types, as we do here, since\nyou don't need to call the intermediate ",(0,o.jsx)(n.code,{children:".bind()"}),"."]}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"val validatedAuthors = authors.withIndex().map { nameAndIx ->\n Author(nameAndIx.value)\n .mapLeft { EmptyAuthor(nameAndIx.index) }\n}.bindAll()\n"})}),"\n",(0,o.jsx)(n.p,{children:"Any of these approaches are equivalent, given that the function that validates\neach of the elements doesn't perform any side effects."})]})}function d(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,o.jsx)(n,{...e,children:(0,o.jsx)(h,{...e})}):h(e)}},11151:(e,n,t)=>{t.d(n,{Z:()=>s,a:()=>a});var o=t(67294);const i={},r=o.createContext(i);function a(e){const n=o.useContext(r);return o.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function s(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:a(e.components),o.createElement(r.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/ac459f8d.5fbd7924.js b/assets/js/ac459f8d.de62200d.js similarity index 82% rename from assets/js/ac459f8d.5fbd7924.js rename to assets/js/ac459f8d.de62200d.js index ab8d4da8..c6ee3be6 100644 --- a/assets/js/ac459f8d.5fbd7924.js +++ b/assets/js/ac459f8d.de62200d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[388],{13619:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/10","page":10,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/9","nextPage":"/community/blog/page/11","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[388],{13619:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/10","page":10,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/9","nextPage":"/community/blog/page/11","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/b0d7ab14.cf6d68a5.js b/assets/js/b0d7ab14.0906e46c.js similarity index 74% rename from assets/js/b0d7ab14.cf6d68a5.js rename to assets/js/b0d7ab14.0906e46c.js index 7ecabed7..0b9d83ed 100644 --- a/assets/js/b0d7ab14.cf6d68a5.js +++ b/assets/js/b0d7ab14.0906e46c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[2153],{50982:a=>{a.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":46,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/6","page":6,"postsPerPage":8,"totalPages":6,"totalCount":46,"previousPage":"/community/blog/tags/articles/page/5","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[2153],{50982:a=>{a.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":47,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/6","page":6,"postsPerPage":8,"totalPages":6,"totalCount":47,"previousPage":"/community/blog/tags/articles/page/5","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/bd30b22e.1240048d.js b/assets/js/bd30b22e.ab785aa6.js similarity index 98% rename from assets/js/bd30b22e.1240048d.js rename to assets/js/bd30b22e.ab785aa6.js index 1a4396e9..f8b0f0df 100644 --- a/assets/js/bd30b22e.1240048d.js +++ b/assets/js/bd30b22e.ab785aa6.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[5866],{40740:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>c,metadata:()=>d,toc:()=>h});var n=t(85893),o=t(11151),i=t(53438),s=t(97048);const c={title:"Typed Errors"},a="",d={id:"learn/typed-errors/index",title:"Typed Errors",description:"Typed errors refer to a technique from functional programming in which we",source:"@site/content/docs/learn/typed-errors/index.md",sourceDirName:"learn/typed-errors",slug:"/learn/typed-errors/",permalink:"/learn/typed-errors/",draft:!1,unlisted:!1,editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/docs/learn/typed-errors/index.md",tags:[],version:"current",frontMatter:{title:"Typed Errors"},sidebar:"learnSidebar",previous:{title:"Migration to Arrow 1.2.0",permalink:"/learn/quickstart/migration"},next:{title:"Working with typed errors",permalink:"/learn/typed-errors/working-with-typed-errors"}},l={},h=[];function p(e){const r={a:"a",code:"code",em:"em",h1:"h1",li:"li",ol:"ol",p:"p",strong:"strong",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h1,{id:"",children:(0,n.jsx)("decorated-text",{icon:(0,i.jA)().customProps.icon,title:c.title})}),"\n",(0,n.jsxs)(r.p,{children:[(0,n.jsx)(r.em,{children:"Typed errors"})," refer to a technique from functional programming in which we\nmake ",(0,n.jsx)(r.em,{children:"explicit"})," in the signature (or ",(0,n.jsx)(r.em,{children:"type"}),") the potential errors that may\narise during the execution of a piece of code. Arrow provides two different\n",(0,n.jsx)(r.strong,{children:"approaches"})," to typed errors:"]}),"\n",(0,n.jsxs)(r.ol,{children:["\n",(0,n.jsxs)(r.li,{children:["The ",(0,n.jsx)(r.code,{children:"Raise"})," DSL uses an extension receiver which represents a ",(0,n.jsx)(r.em,{children:"context"}),"\nin which errors of a certain type may be raises. This approach often results\nin more idiomatic code."]}),"\n",(0,n.jsxs)(r.li,{children:["Using ",(0,n.jsx)(r.em,{children:"wrapper types"}),", like ",(0,n.jsx)(r.code,{children:"Either"}),", ",(0,n.jsx)(r.code,{children:"Option"}),", or ",(0,n.jsx)(r.code,{children:"Result"}),", we indicate\nthat a computation may end with a logical error by decorating the return\ntype."]}),"\n"]}),"\n",(0,n.jsx)(r.p,{children:"Regardless of your choice, Arrow provides a uniform API, and simple ways to\nmove from one style to the other."}),"\n",(0,n.jsxs)(r.p,{children:["If you want a ",(0,n.jsx)(r.strong,{children:"general introduction"})," we recommend the tutorial about\n",(0,n.jsx)(r.a,{href:"/learn/typed-errors/working-with-typed-errors",children:"working with typed errors"}),", followed by\nhow to model ",(0,n.jsx)(r.a,{href:"/learn/typed-errors/validation",children:"validation"})," in this style."]}),"\n",(0,n.jsxs)(r.p,{children:["If you are already ",(0,n.jsxs)(r.strong,{children:["familiar with ",(0,n.jsx)(r.code,{children:"Either"})]})," and similar wrapper types,\nyou can find information about their Arrow counterparts\n(",(0,n.jsxs)(r.a,{href:"/learn/typed-errors/nullable-and-option",children:["Nullable and ",(0,n.jsx)(r.code,{children:"Option"})]}),", ",(0,n.jsxs)(r.a,{href:"/learn/typed-errors/either-and-ior",children:[(0,n.jsx)(r.code,{children:"Either"})," and ",(0,n.jsx)(r.code,{children:"Ior"})]}),").\nWe stongly recommend to read ",(0,n.jsxs)(r.a,{href:"/learn/typed-errors/from-either-to-raise",children:["From ",(0,n.jsx)(r.code,{children:"Either"})," to ",(0,n.jsx)(r.code,{children:"Raise"})]})," to understand\nhow you can benefit from the typed errors DSL."]}),"\n",(0,n.jsx)(s.Z,{})]})}function m(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},66569:(e,r,t)=>{t.d(r,{k:()=>m});t(67294);var n=t(33692),o=t(44996);const i="linkCard_uxt7",s="icon_lqTJ",c="cardHeader_NaDd",a="cardBody_svEQ",d="paragraph_UbEf";var l=t(85893);function h(e){let{href:r,children:t}=e;return(0,l.jsx)(n.Z,{href:r,className:i,children:t})}function p(e){let{title:r,icon:t,body:n}=e;return(0,l.jsxs)("div",{className:"card",children:[(0,l.jsxs)("div",{className:`card__header ${c}`,children:[(0,l.jsx)("img",{className:s,src:(0,o.Z)(`/img/${t}`),alt:`${r} category`,title:`${r} category`,width:"48px",height:"48px"}),(0,l.jsx)("h2",{title:r,className:"text--truncate",children:r})]}),(0,l.jsx)("div",{className:`card__body ${a}`,children:(0,l.jsx)("p",{className:`${d}`,children:n})})]})}const m=e=>(0,l.jsx)(h,{href:e.href,children:(0,l.jsx)(p,{...e})})},97048:(e,r,t)=>{t.d(r,{Z:()=>l});t(67294);var n=t(53438),o=t(66569),i=t(85893);const s="icon-tutorial.svg";function c(e){let{item:r}=e;const t=function(){try{return(0,n.jA)()}catch{return}}()?.customProps?.icon,c={title:r.label,icon:r.customProps?.icon||t||s,href:r.href,body:r.customProps?.description??("link"===r.type&&(0,n.xz)(r.docId??void 0)).description??void 0};return(0,i.jsx)(o.k,{...c})}const a={container:"container_Mg1N"};function d(e){let{className:r}=e;const t=(0,n.jA)();return(0,i.jsx)(l,{items:t.items,className:r})}function l(e){const{items:r,className:t}=e;if(!r)return(0,i.jsx)(d,{...e});const o=(0,n.MN)(r);return(0,i.jsx)("section",{className:`${a.container} ${t}`,children:o.map(((e,r)=>(0,i.jsx)("article",{children:(0,i.jsx)(c,{item:e})},r)))})}},11151:(e,r,t)=>{t.d(r,{Z:()=>c,a:()=>s});var n=t(67294);const o={},i=n.createContext(o);function s(e){const r=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function c(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(i.Provider,{value:r},e.children)}}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[5866],{40740:(e,r,t)=>{t.r(r),t.d(r,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>c,metadata:()=>d,toc:()=>h});var n=t(85893),o=t(11151),i=t(53438),s=t(97048);const c={title:"Typed Errors"},a="",d={id:"learn/typed-errors/index",title:"Typed Errors",description:"Typed errors refer to a technique from functional programming in which we",source:"@site/content/docs/learn/typed-errors/index.md",sourceDirName:"learn/typed-errors",slug:"/learn/typed-errors/",permalink:"/learn/typed-errors/",draft:!1,unlisted:!1,editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/docs/learn/typed-errors/index.md",tags:[],version:"current",frontMatter:{title:"Typed Errors"},sidebar:"learnSidebar",previous:{title:"Migration to Arrow 1.2.0",permalink:"/learn/quickstart/migration"},next:{title:"Working with typed errors",permalink:"/learn/typed-errors/working-with-typed-errors"}},l={},h=[];function p(e){const r={a:"a",code:"code",em:"em",h1:"h1",li:"li",ol:"ol",p:"p",strong:"strong",...(0,o.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(r.h1,{id:"",children:(0,n.jsx)("decorated-text",{icon:(0,i.jA)().customProps.icon,title:c.title})}),"\n",(0,n.jsxs)(r.p,{children:[(0,n.jsx)(r.em,{children:"Typed errors"})," refer to a technique from functional programming in which we\nmake ",(0,n.jsx)(r.em,{children:"explicit"})," in the signature (or ",(0,n.jsx)(r.em,{children:"type"}),") the potential errors that may\narise during the execution of a piece of code. Arrow provides two different\n",(0,n.jsx)(r.strong,{children:"approaches"})," to typed errors:"]}),"\n",(0,n.jsxs)(r.ol,{children:["\n",(0,n.jsxs)(r.li,{children:["The ",(0,n.jsx)(r.code,{children:"Raise"})," DSL uses an extension receiver which represents a ",(0,n.jsx)(r.em,{children:"context"}),"\nin which errors of a certain type may be raised. This approach often results\nin more idiomatic code."]}),"\n",(0,n.jsxs)(r.li,{children:["Using ",(0,n.jsx)(r.em,{children:"wrapper types"}),", like ",(0,n.jsx)(r.code,{children:"Either"}),", ",(0,n.jsx)(r.code,{children:"Option"}),", or ",(0,n.jsx)(r.code,{children:"Result"}),", we indicate\nthat a computation may end with a logical error by decorating the return\ntype."]}),"\n"]}),"\n",(0,n.jsx)(r.p,{children:"Regardless of your choice, Arrow provides a uniform API, and simple ways to\nmove from one style to the other."}),"\n",(0,n.jsxs)(r.p,{children:["If you want a ",(0,n.jsx)(r.strong,{children:"general introduction"})," we recommend the tutorial about\n",(0,n.jsx)(r.a,{href:"/learn/typed-errors/working-with-typed-errors",children:"working with typed errors"}),", followed by\nhow to model ",(0,n.jsx)(r.a,{href:"/learn/typed-errors/validation",children:"validation"})," in this style."]}),"\n",(0,n.jsxs)(r.p,{children:["If you are already ",(0,n.jsxs)(r.strong,{children:["familiar with ",(0,n.jsx)(r.code,{children:"Either"})]})," and similar wrapper types,\nyou can find information about their Arrow counterparts\n(",(0,n.jsxs)(r.a,{href:"/learn/typed-errors/nullable-and-option",children:["Nullable and ",(0,n.jsx)(r.code,{children:"Option"})]}),", ",(0,n.jsxs)(r.a,{href:"/learn/typed-errors/either-and-ior",children:[(0,n.jsx)(r.code,{children:"Either"})," and ",(0,n.jsx)(r.code,{children:"Ior"})]}),").\nWe stongly recommend to read ",(0,n.jsxs)(r.a,{href:"/learn/typed-errors/from-either-to-raise",children:["From ",(0,n.jsx)(r.code,{children:"Either"})," to ",(0,n.jsx)(r.code,{children:"Raise"})]})," to understand\nhow you can benefit from the typed errors DSL."]}),"\n",(0,n.jsx)(s.Z,{})]})}function m(e={}){const{wrapper:r}={...(0,o.a)(),...e.components};return r?(0,n.jsx)(r,{...e,children:(0,n.jsx)(p,{...e})}):p(e)}},66569:(e,r,t)=>{t.d(r,{k:()=>m});t(67294);var n=t(33692),o=t(44996);const i="linkCard_uxt7",s="icon_lqTJ",c="cardHeader_NaDd",a="cardBody_svEQ",d="paragraph_UbEf";var l=t(85893);function h(e){let{href:r,children:t}=e;return(0,l.jsx)(n.Z,{href:r,className:i,children:t})}function p(e){let{title:r,icon:t,body:n}=e;return(0,l.jsxs)("div",{className:"card",children:[(0,l.jsxs)("div",{className:`card__header ${c}`,children:[(0,l.jsx)("img",{className:s,src:(0,o.Z)(`/img/${t}`),alt:`${r} category`,title:`${r} category`,width:"48px",height:"48px"}),(0,l.jsx)("h2",{title:r,className:"text--truncate",children:r})]}),(0,l.jsx)("div",{className:`card__body ${a}`,children:(0,l.jsx)("p",{className:`${d}`,children:n})})]})}const m=e=>(0,l.jsx)(h,{href:e.href,children:(0,l.jsx)(p,{...e})})},97048:(e,r,t)=>{t.d(r,{Z:()=>l});t(67294);var n=t(53438),o=t(66569),i=t(85893);const s="icon-tutorial.svg";function c(e){let{item:r}=e;const t=function(){try{return(0,n.jA)()}catch{return}}()?.customProps?.icon,c={title:r.label,icon:r.customProps?.icon||t||s,href:r.href,body:r.customProps?.description??("link"===r.type&&(0,n.xz)(r.docId??void 0)).description??void 0};return(0,i.jsx)(o.k,{...c})}const a={container:"container_Mg1N"};function d(e){let{className:r}=e;const t=(0,n.jA)();return(0,i.jsx)(l,{items:t.items,className:r})}function l(e){const{items:r,className:t}=e;if(!r)return(0,i.jsx)(d,{...e});const o=(0,n.MN)(r);return(0,i.jsx)("section",{className:`${a.container} ${t}`,children:o.map(((e,r)=>(0,i.jsx)("article",{children:(0,i.jsx)(c,{item:e})},r)))})}},11151:(e,r,t)=>{t.d(r,{Z:()=>c,a:()=>s});var n=t(67294);const o={},i=n.createContext(o);function s(e){const r=n.useContext(i);return n.useMemo((function(){return"function"==typeof e?e(r):{...r,...e}}),[r,e])}function c(e){let r;return r=e.disableParentContext?"function"==typeof e.components?e.components(o):e.components||o:s(e.components),n.createElement(i.Provider,{value:r},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c3eb2edf.0a62655b.js b/assets/js/c3eb2edf.0a62655b.js new file mode 100644 index 00000000..fd6436aa --- /dev/null +++ b/assets/js/c3eb2edf.0a62655b.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[2579],{86284:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var t=r(85893),i=r(11151);const o={title:"Arrow plug-in for IntelliJ 0.1 is here!",category:"articles",tags:["intellij","articles"]},s="Arrow plug-in for IntelliJ 0.1 is here!",l={permalink:"/community/blog/2024/06/01/intellij-plugin",editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-06-01-intellij-plugin.md",source:"@site/content/blog/2024-06-01-intellij-plugin.md",title:"Arrow plug-in for IntelliJ 0.1 is here!",description:"One of the main goals of the Arrow project is to produce libraries",date:"2024-06-01T00:00:00.000Z",tags:[{label:"intellij",permalink:"/community/blog/tags/intellij"},{label:"articles",permalink:"/community/blog/tags/articles"}],readingTime:1.41,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Arrow plug-in for IntelliJ 0.1 is here!",category:"articles",tags:["intellij","articles"]},unlisted:!1,prevItem:{title:"Arrow Open Space @ Lambda World",permalink:"/community/blog/2024/10/03/arrow-open-space"},nextItem:{title:"Arrow 1.2.3 release",permalink:"/community/blog/2024/02/28/arrow-1-2-3"}},a={authorsImageUrls:[]},c=[];function d(e){const n={a:"a",code:"code",p:"p",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["One of the main goals of the Arrow project is to produce libraries\nthat follow well-known Kotlin idioms, and we strive to make them\nas discoverable as possible. Nevertheless, the surface of some\ncomponents, like ",(0,t.jsx)(n.a,{href:"/learn/typed-errors/",children:"typed errors"}),",\nis quite large.\nFor that reason, we have been busy in the last weeks preparing\nthe first release of the\n",(0,t.jsx)(n.a,{href:"https://plugins.jetbrains.com/plugin/24550-arrow",children:"Arrow plug-in for IntelliJ-based IDEs"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["This first version already focuses on three different aspects of\nArrow usage where we found that an additional companion can make\na big difference. The first aspect is the usage of typed errors:\nthe IDE will now suggest missing ",(0,t.jsx)(n.code,{children:".bind()"})," or ",(0,t.jsx)(n.code,{children:".bindAll()"}),",\nmapping of error using ",(0,t.jsx)(n.code,{children:"withError"}),", and promoting idioms like\n",(0,t.jsx)(n.code,{children:"ensure"})," whenever possible."]}),"\n",(0,t.jsxs)(n.p,{children:["The second aspect is warning about wrong usages of Arrow APIs\nwhich cannot be prevented by Kotlin's type system alone. This includes\nescaping of ",(0,t.jsx)(n.code,{children:"Raise"})," contexts -- for example, using ",(0,t.jsx)(n.code,{children:"sequence"})," or\n",(0,t.jsx)(n.code,{children:"flow"})," inside ",(0,t.jsx)(n.code,{children:"either"})," --, using ",(0,t.jsx)(n.code,{children:"Atomic"})," with primitive types\n-- where ",(0,t.jsx)(n.code,{children:"AtomicInt"})," or ",(0,t.jsx)(n.code,{children:"AtomicBoolean"})," should be used instead --,\nor matching on ",(0,t.jsx)(n.code,{children:"Eval"})," instances directly instead of using the\nprovided API -- which can easily lead to broken invariants."]}),"\n",(0,t.jsxs)(n.p,{children:["The third aspect is applying some known recipes which may be hard\nto know upfront. The first release includes a suggestion to add\nthe corresponding ",(0,t.jsx)(n.a,{href:"/learn/quickstart/serialization/",children:"serializer"}),"\nwhen a type marked as ",(0,t.jsx)(n.code,{children:"@Serializable"})," includes an Arrow Core type.\nThis is an area which we would like to explore more, helping with\nthe difficulties raised by the community."]}),"\n",(0,t.jsxs)(n.p,{children:["The plug-in lives in a ",(0,t.jsx)(n.a,{href:"https://github.com/arrow-kt/arrow-intellij",children:"separate repository"}),".\nPlease let us know your experience, and don't be shy to open issues\nwith suggestions for more features. They would help not only you\nbut potentially every user of the Arrow library."]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>s});var t=r(67294);const i={},o=t.createContext(i);function s(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c3eb2edf.f2d68197.js b/assets/js/c3eb2edf.f2d68197.js deleted file mode 100644 index e95327ad..00000000 --- a/assets/js/c3eb2edf.f2d68197.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[2579],{86284:(e,n,r)=>{r.r(n),r.d(n,{assets:()=>a,contentTitle:()=>s,default:()=>h,frontMatter:()=>o,metadata:()=>l,toc:()=>c});var t=r(85893),i=r(11151);const o={title:"Arrow plug-in for IntelliJ 0.1 is here!",category:"articles",tags:["intellij","articles"]},s="Arrow plug-in for IntelliJ 0.1 is here!",l={permalink:"/community/blog/2024/06/01/intellij-plugin",editUrl:"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-06-01-intellij-plugin.md",source:"@site/content/blog/2024-06-01-intellij-plugin.md",title:"Arrow plug-in for IntelliJ 0.1 is here!",description:"One of the main goals of the Arrow project is to produce libraries",date:"2024-06-01T00:00:00.000Z",tags:[{label:"intellij",permalink:"/community/blog/tags/intellij"},{label:"articles",permalink:"/community/blog/tags/articles"}],readingTime:1.41,hasTruncateMarker:!1,authors:[],frontMatter:{title:"Arrow plug-in for IntelliJ 0.1 is here!",category:"articles",tags:["intellij","articles"]},unlisted:!1,nextItem:{title:"Arrow 1.2.3 release",permalink:"/community/blog/2024/02/28/arrow-1-2-3"}},a={authorsImageUrls:[]},c=[];function d(e){const n={a:"a",code:"code",p:"p",...(0,i.a)(),...e.components};return(0,t.jsxs)(t.Fragment,{children:[(0,t.jsxs)(n.p,{children:["One of the main goals of the Arrow project is to produce libraries\nthat follow well-known Kotlin idioms, and we strive to make them\nas discoverable as possible. Nevertheless, the surface of some\ncomponents, like ",(0,t.jsx)(n.a,{href:"/learn/typed-errors/",children:"typed errors"}),",\nis quite large.\nFor that reason, we have been busy in the last weeks preparing\nthe first release of the\n",(0,t.jsx)(n.a,{href:"https://plugins.jetbrains.com/plugin/24550-arrow",children:"Arrow plug-in for IntelliJ-based IDEs"}),"."]}),"\n",(0,t.jsxs)(n.p,{children:["This first version already focuses on three different aspects of\nArrow usage where we found that an additional companion can make\na big difference. The first aspect is the usage of typed errors:\nthe IDE will now suggest missing ",(0,t.jsx)(n.code,{children:".bind()"})," or ",(0,t.jsx)(n.code,{children:".bindAll()"}),",\nmapping of error using ",(0,t.jsx)(n.code,{children:"withError"}),", and promoting idioms like\n",(0,t.jsx)(n.code,{children:"ensure"})," whenever possible."]}),"\n",(0,t.jsxs)(n.p,{children:["The second aspect is warning about wrong usages of Arrow APIs\nwhich cannot be prevented by Kotlin's type system alone. This includes\nescaping of ",(0,t.jsx)(n.code,{children:"Raise"})," contexts -- for example, using ",(0,t.jsx)(n.code,{children:"sequence"})," or\n",(0,t.jsx)(n.code,{children:"flow"})," inside ",(0,t.jsx)(n.code,{children:"either"})," --, using ",(0,t.jsx)(n.code,{children:"Atomic"})," with primitive types\n-- where ",(0,t.jsx)(n.code,{children:"AtomicInt"})," or ",(0,t.jsx)(n.code,{children:"AtomicBoolean"})," should be used instead --,\nor matching on ",(0,t.jsx)(n.code,{children:"Eval"})," instances directly instead of using the\nprovided API -- which can easily lead to broken invariants."]}),"\n",(0,t.jsxs)(n.p,{children:["The third aspect is applying some known recipes which may be hard\nto know upfront. The first release includes a suggestion to add\nthe corresponding ",(0,t.jsx)(n.a,{href:"/learn/quickstart/serialization/",children:"serializer"}),"\nwhen a type marked as ",(0,t.jsx)(n.code,{children:"@Serializable"})," includes an Arrow Core type.\nThis is an area which we would like to explore more, helping with\nthe difficulties raised by the community."]}),"\n",(0,t.jsxs)(n.p,{children:["The plug-in lives in a ",(0,t.jsx)(n.a,{href:"https://github.com/arrow-kt/arrow-intellij",children:"separate repository"}),".\nPlease let us know your experience, and don't be shy to open issues\nwith suggestions for more features. They would help not only you\nbut potentially every user of the Arrow library."]})]})}function h(e={}){const{wrapper:n}={...(0,i.a)(),...e.components};return n?(0,t.jsx)(n,{...e,children:(0,t.jsx)(d,{...e})}):d(e)}},11151:(e,n,r)=>{r.d(n,{Z:()=>l,a:()=>s});var t=r(67294);const i={},o=t.createContext(i);function s(e){const n=t.useContext(o);return t.useMemo((function(){return"function"==typeof e?e(n):{...n,...e}}),[n,e])}function l(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(i):e.components||i:s(e.components),t.createElement(o.Provider,{value:n},e.children)}}}]); \ No newline at end of file diff --git a/assets/js/c4390de3.5709eecc.js b/assets/js/c4390de3.4b32015f.js similarity index 82% rename from assets/js/c4390de3.5709eecc.js rename to assets/js/c4390de3.4b32015f.js index 196d941e..86a2ae30 100644 --- a/assets/js/c4390de3.5709eecc.js +++ b/assets/js/c4390de3.4b32015f.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[2123],{53653:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/8","page":8,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/7","nextPage":"/community/blog/page/9","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[2123],{53653:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/8","page":8,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/7","nextPage":"/community/blog/page/9","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/e41df212.51c4aeaf.js b/assets/js/e41df212.51c4aeaf.js deleted file mode 100644 index 5a3ef9d4..00000000 --- a/assets/js/e41df212.51c4aeaf.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[2348],{22761:e=>{e.exports=JSON.parse('{"archive":{"blogPosts":[{"id":"/2024/06/01/intellij-plugin","metadata":{"permalink":"/community/blog/2024/06/01/intellij-plugin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-06-01-intellij-plugin.md","source":"@site/content/blog/2024-06-01-intellij-plugin.md","title":"Arrow plug-in for IntelliJ 0.1 is here!","description":"One of the main goals of the Arrow project is to produce libraries","date":"2024-06-01T00:00:00.000Z","tags":[{"label":"intellij","permalink":"/community/blog/tags/intellij"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":1.41,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow plug-in for IntelliJ 0.1 is here!","category":"articles","tags":["intellij","articles"]},"unlisted":false,"nextItem":{"title":"Arrow 1.2.3 release","permalink":"/community/blog/2024/02/28/arrow-1-2-3"}},"content":"One of the main goals of the Arrow project is to produce libraries\\nthat follow well-known Kotlin idioms, and we strive to make them\\nas discoverable as possible. Nevertheless, the surface of some\\ncomponents, like [typed errors](/learn/typed-errors/),\\nis quite large.\\nFor that reason, we have been busy in the last weeks preparing\\nthe first release of the\\n[Arrow plug-in for IntelliJ-based IDEs](https://plugins.jetbrains.com/plugin/24550-arrow).\\n\\nThis first version already focuses on three different aspects of\\nArrow usage where we found that an additional companion can make\\na big difference. The first aspect is the usage of typed errors:\\nthe IDE will now suggest missing `.bind()` or `.bindAll()`,\\nmapping of error using `withError`, and promoting idioms like\\n`ensure` whenever possible.\\n\\nThe second aspect is warning about wrong usages of Arrow APIs\\nwhich cannot be prevented by Kotlin\'s type system alone. This includes\\nescaping of `Raise` contexts -- for example, using `sequence` or\\n`flow` inside `either` --, using `Atomic` with primitive types \\n-- where `AtomicInt` or `AtomicBoolean` should be used instead --,\\nor matching on `Eval` instances directly instead of using the\\nprovided API -- which can easily lead to broken invariants.\\n\\nThe third aspect is applying some known recipes which may be hard\\nto know upfront. The first release includes a suggestion to add\\nthe corresponding [serializer](/learn/quickstart/serialization/)\\nwhen a type marked as `@Serializable` includes an Arrow Core type.\\nThis is an area which we would like to explore more, helping with\\nthe difficulties raised by the community.\\n\\nThe plug-in lives in a [separate repository](https://github.com/arrow-kt/arrow-intellij).\\nPlease let us know your experience, and don\'t be shy to open issues\\nwith suggestions for more features. They would help not only you\\nbut potentially every user of the Arrow library."},{"id":"/2024/02/28/arrow-1-2-3","metadata":{"permalink":"/community/blog/2024/02/28/arrow-1-2-3","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-02-28-arrow-1-2-3.md","source":"@site/content/blog/2024-02-28-arrow-1-2-3.md","title":"Arrow 1.2.3 release","description":"We are happy to announce the availability of version 1.2.3 of the Arrow collection of libraries.","date":"2024-02-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":4.65,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 1.2.3 release","category":"articles","tags":["core","articles"]},"unlisted":false,"prevItem":{"title":"Arrow plug-in for IntelliJ 0.1 is here!","permalink":"/community/blog/2024/06/01/intellij-plugin"},"nextItem":{"title":"Arrow releases stable 1.2.0 version","permalink":"/community/blog/2023/07/12/arrow-1-2-0"}},"content":"We are happy to announce the availability of version 1.2.3 of the Arrow collection of libraries.\\nAccording to our plan, this is the last non-bugfix release of the 1.x series.\\nFrom now on, our `main` branch targets Arrow 2.0, which should be the next major release.\\n\\nWe are incredibly thankful to the many people that have contributed to this release,\\nbringing new ideas and quite some code.\\n\\n:::info Please use 1.2.4\\n\\nVersion 1.2.3 of `arrow-core` changed the behavior of `Raise` computations returning\\nfunctions or sequences. This change [restricted some useful usages](https://github.com/arrow-kt/arrow/issues/3391),\\nso the team has decided to roll it back and keep the 1.2.1 behavior.\\n\\n:::\\n\\n## New features\\n\\nA version number like 1.2.3 sounds like a small bugfix release, but this is far from truth in\\nthis case: this release is full of new modules to help you be productive when writing Kotlin.\\n\\n### Improved focus on Compose\\n\\nArrow provides building blocks relevant to many projects using Kotlin.\\nA large part of our community is doing frontend work, and during the latest months,\\nthe team has been trying to understand their needs, in order to make Arrow\\na relevant tool in that space.\\n\\nFrom that journey, we have put together a new documentation page highlighting\\ndifferent ways in which Arrow may be useful in your Compose application.\\nThere is also a new [`arrow-optics-compose` module](/learn/immutable-data/lens/#integration-with-compose)\\nthat includes utilities to work with immutable data inside a `MutableState`\\nor `MutableStateFlow`.\\n\\nWe are eager to hear more use cases or needs where Arrow may help the lives\\nof Kotlin developers. Feel free to drop by the `#arrow` channel in the Kotlin Slack,\\nor open an issue or discussion in our [repository](https://github.com/arrow-kt/arrow).\\n\\n### Non-`suspend` resource management\\n\\n[Resource safety](/learn/coroutines/resource-safety/) in Arrow\\nhas been traditionally tied to the use of coroutines and `suspend` functions.\\nThis is the right choice for Kotlin-first libraries, like Ktor or Koin, but many\\nlibraries still come from a Java background where no such feature exists.\\nBeginning with this version, we provide two \\"variations\\" of resource management:\\n\\n- `Resource`, from the `arrow-fx-coroutines` module, is based on `suspend`\\n and ensures the desired behavior alongside coroutines (including cancellation).\\n- `AutoClose`, from the new `arrow-autoclose` module, provides almost the\\n same API as `Resource`, but without the `suspend` requirement.\\n\\n### Forward compatible `Eval`\\n\\nOne of our goals is to make the transition to 2.0 as smooth as possible.\\nYou can [already migrate](/learn/quickstart/migration/)\\nto the new APIs by using Arrow 1.2.3, and then ensuring that you get no deprecation warnings.\\n\\nDuring this process, we were [made aware](https://github.com/arrow-kt/arrow/issues/3039) that\\nthere was no clear story for the migration of `Eval`. On the other hand, the use cases are very narrow.\\nThe decision was to create a new [`arrow-eval` module](/learn/collections-functions/eval/),\\npresent since this release, and mark the one from `arrow-core` point the new module,\\ninstead of entirely removing this functionality from Arrow.\\n\\n### Collectors\\n\\nThe new [`arrow-collectors` module](/learn/collections-functions/collectors/)\\nallows composing operations over sequences of values\\n(lists, flows, sequences) while ensuring that the sequence is traversed only once.\\nThis property is especially relevant when building the sequence is expensive, or simply\\ncannot be reproduced, like a stream of data from a database or a flow of actions.\\n\\n## Improved features\\n\\nSeveral features in the library have been improved, to ensure that Arrow covers a variety\\nof use cases.\\n\\n### Lenses for sealed classes\\n\\nThis was once of the [older feature requests](https://github.com/arrow-kt/arrow/issues/2829)\\nstill in our issue tracker, which is now closed thanks to a wonderful\\n[contribution](https://github.com/arrow-kt/arrow/pull/3359)!\\n\\nFrom now on, the Optics KSP plug-in can generate\\n[lenses for sealed hierarchies](/learn/immutable-data/lens/#sealed-class-hierarchies),\\ngiven that the field lives in the common parent. For example, the following code\\n\\n```kotlin\\n@optics sealed interface User {\\n val name: String\\n\\n data class Person(override val name: String, val age: Int): User\\n data class Company(override val name: String, val vat: VATNumber): User\\n}\\n```\\n\\ngenerates from this version on both prisms for each choice, and a lens for `name`.\\n\\n### Higher-arity functions\\n\\nWe have traditionally been reluctant to add variations of `zip` with more than\\n10 parameters, because we felt that the narrow use cases did not balance out\\nthe increase in binary size. Since this release Arrow provides those functions\\nin a new `arrow-core-high-arity` module.\\n\\n### More accumulating functions for `Raise`\\n\\n[Typed errors](/learn/typed-errors/working-with-typed-errors/)\\nprovide two essential ways to [accumulate errors](/learn/typed-errors/working-with-typed-errors/#accumulating-errors): `zipOrAccumulate` and `mapOrAccumulate`. Those correspond\\nto accumulating over a fixed number of computations of different types, or\\naccumulating over an unknown quantity of computations with the same type.\\n\\nThe `mapOrAccumulate` function _always_ returns a new list. In some cases, you\\ndon\'t really care about this result, just about the iteration behavior.\\nThis is similar to the different between `map` and `forEach` in the standard\\nlibrary. From there Arrow takes the name of the new function: `forEachAccumulating`.\\n\\nOne potential use case is performing validation over elements of a list,\\nbut keeping the values intact.\\n\\n```kotlin\\npeople.forEachAccumulating { person ->\\n ensure(person.age >= 0) { InvalidAge(person.name) }\\n}\\n```\\n\\n### Better memoization\\n\\n[`MemoizedDeepRecursiveFunction`](/learn/collections-functions/recursive/#memoized-recursive-functions)\\nis a powerful tool to express recursive algorithms without worries over stack overflow or recomputation.\\nHowever, there was a lack of control over how memoized values were stored or evicted, which made the\\ntype less useful than intended.\\n\\nFrom this release on, there are new overloads to support custom memoization policies.\\nFurthermore, the new [`arrow-cache4k` module](/learn/collections-functions/recursive/#memoization-takes-memory)\\nprovides integration with the excellent\\n[cache4k](https://github.com/ReactiveCircus/cache4k) library.\\n\\n## More integrations\\n\\nAlthough not part of this release, we would like to highlight that\\n[Akkurate](https://akkurate.dev), which provides a wonderful DSL for validation over data,\\nhas released an [integration module for Arrow](https://akkurate.dev/docs/arrow-integration.html).\\nThis adds to the [rest of integrations](/learn/integrations/)\\nand shows the collaborative spirit of the Kotlin community."},{"id":"/2023/07/12/arrow-1-2-0","metadata":{"permalink":"/community/blog/2023/07/12/arrow-1-2-0","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-07-12-arrow-1-2-0.md","source":"@site/content/blog/2023-07-12-arrow-1-2-0.md","title":"Arrow releases stable 1.2.0 version","description":"We\'re excited to announce the stable Arrow 1.2.0 version. To briefly summarize, this release:","date":"2023-07-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.32,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow releases stable 1.2.0 version","image":"https://xebia.com/wp-content/uploads/2023/04/arrow-release-ftr.jpg","category":"articles","tags":["core","articles"],"link":"https://xebia.com/blog/a-new-module-for-typed-errors-in-arrow-1-2-0/"},"unlisted":false,"prevItem":{"title":"Arrow 1.2.3 release","permalink":"/community/blog/2024/02/28/arrow-1-2-3"},"nextItem":{"title":"Arrow 2.0\'s Trajectory - Video","permalink":"/community/blog/2023/05/04/arrow-trajectory-kotlinconf"}},"content":"We\'re excited to announce the stable Arrow 1.2.0 version. To briefly summarize, this release:\\n\\n- Improves the API for [typed errors](http://arrow-kt.io/learn/typed-errors/working-with-typed-errors/),\\n including [`withError`](https://apidocs.arrow-kt.io/arrow-core/arrow.core.raise/with-error.html)\\n and [`merge`](https://apidocs.arrow-kt.io/arrow-core/arrow.core.raise/merge.html).\\n- Adds [`NonEmptyCollection`](https://apidocs.arrow-kt.io/arrow-core/arrow.core/-non-empty-collection/index.html)\\n as common parent of [`NonEmptyList`](https://apidocs.arrow-kt.io/arrow-core/arrow.core/-non-empty-list/index.html)\\n and [`NonEmptySet`](https://apidocs.arrow-kt.io/arrow-core/arrow.core/-non-empty-set/index.html).\\n- Introduces [`arrow-core-serialization`](https://arrow-kt.io/learn/quickstart/serialization/)\\n to be used alongside KotlinX Serialization.\\n- Fixes a few issues found in the Release Candidate.\\n\\nRead more details in the full [Arrow 1.2.0 release announcement](https://xebia.com/blog/a-new-module-for-typed-errors-in-arrow-1-2-0/)."},{"id":"/2023/05/04/arrow-trajectory-kotlinconf","metadata":{"permalink":"/community/blog/2023/05/04/arrow-trajectory-kotlinconf","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-05-04-arrow-trajectory-kotlinconf.md","source":"@site/content/blog/2023-05-04-arrow-trajectory-kotlinconf.md","title":"Arrow 2.0\'s Trajectory - Video","description":"Watch Simon Vergauwen\'s presentation from KotlinConf 2023 about the history of Arrow, and the trajectory for Arrow 2.0.","date":"2023-05-04T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.09,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 2.0\'s Trajectory - Video","image":"https://img.youtube.com/vi/tplA17M9Y4Q/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/tplA17M9Y4Q","event":"KotlinConf"},"unlisted":false,"prevItem":{"title":"Arrow releases stable 1.2.0 version","permalink":"/community/blog/2023/07/12/arrow-1-2-0"},"nextItem":{"title":"Nicer data transformation with KopyKat and Optics","permalink":"/community/blog/2023/05/04/data-transformation-kotlinconf"}},"content":"Watch [Simon Vergauwen](https://twitter.com/vergauwen_simon)\'s presentation from KotlinConf 2023 about the history of Arrow, and the trajectory for Arrow 2.0."},{"id":"/2023/05/04/data-transformation-kotlinconf","metadata":{"permalink":"/community/blog/2023/05/04/data-transformation-kotlinconf","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-05-04-data-transformation-kotlinconf.md","source":"@site/content/blog/2023-05-04-data-transformation-kotlinconf.md","title":"Nicer data transformation with KopyKat and Optics","description":"Watch Alejandro Serrano\'s presentation from KotlinConf 2023 about data transformation.","date":"2023-05-04T00:00:00.000Z","tags":[{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.365,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Nicer data transformation with KopyKat and Optics","image":"https://img.youtube.com/vi/atV8liVgd3w/maxresdefault.jpg","category":"videos","tags":["optics","videos"],"link":"https://youtu.be/atV8liVgd3w","event":"KotlinConf"},"unlisted":false,"prevItem":{"title":"Arrow 2.0\'s Trajectory - Video","permalink":"/community/blog/2023/05/04/arrow-trajectory-kotlinconf"},"nextItem":{"title":"Typed Error Handling in Kotlin","permalink":"/community/blog/2023/04/17/typed-error-handling-in-kotlin"}},"content":"Watch [Alejandro Serrano](https://twitter.com/trupill)\'s presentation from KotlinConf 2023 about data transformation.\\n\\nData classes are incredibly useful when modeling our domain in an immutable way. The Kotlin compiler gives us many niceties, including \'copy\' to create a new value based on a previous one. However, this \'copy\' often falls short. This talk explores two alternatives: KopyKat, a plug-in to generate additional variations of \'copy\', and Arrow Optics, a whole framework to transform this immutable data."},{"id":"/2023/04/17/typed-error-handling-in-kotlin","metadata":{"permalink":"/community/blog/2023/04/17/typed-error-handling-in-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-04-17-typed-error-handling-in-kotlin.md","source":"@site/content/blog/2023-04-17-typed-error-handling-in-kotlin.md","title":"Typed Error Handling in Kotlin","description":"A comparative study about several typed-error handling practices in Kotlin.","date":"2023-04-17T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.585,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Typed Error Handling in Kotlin","image":"https://miro.medium.com/v2/resize:fit:4800/0*kOFUN-7oR7gyGXu_","category":"articles","tags":["core","articles"],"link":"https://medium.com/@mitchellyuwono/typed-error-handling-in-kotlin-11ff25882880"},"unlisted":false,"prevItem":{"title":"Nicer data transformation with KopyKat and Optics","permalink":"/community/blog/2023/05/04/data-transformation-kotlinconf"},"nextItem":{"title":"Arrow 2.0\'s Trajectory","permalink":"/community/blog/2023/04/16/arrow-2-0-trajectory"}},"content":"A comparative study about several typed-error handling practices in Kotlin.\\n\\nThere are various approaches to error handling in the Kotlin community. \\nIn this article we\u2019ve explored a small subset of typed error handling practices in the community. \\n\\nFrom the approaches explored, there were three patterns that aligns with Kotlin recommendation with \\nrelatively low cognitive complexity including: Sealed class matching with early returns, Arrow\'s `either { }` builder, \\nand Arrow\'s `context(Raise)` with context-receivers. \\n\\nArrow\'s `context(Raise)` achieved the most optimized score on all aspects of \\ndeveloper productivity. This includes having the lowest cognitive complexity, the lowest cyclomatic complexity \\nas well as the most succinct with the least lines of codes.\\n\\nRead the full article: [Typed Error Handling in Kotlin](https://medium.com/@mitchellyuwono/typed-error-handling-in-kotlin-11ff25882880)."},{"id":"/2023/04/16/arrow-2-0-trajectory","metadata":{"permalink":"/community/blog/2023/04/16/arrow-2-0-trajectory","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-04-16-arrow-2-0-trajectory.md","source":"@site/content/blog/2023-04-16-arrow-2-0-trajectory.md","title":"Arrow 2.0\'s Trajectory","description":"A full transcript and the slides from Simon Vergauwen\'s presentation from KotlinConf 2023 about the history of Arrow and where it\'s going.","date":"2023-04-16T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 2.0\'s Trajectory","image":"https://nomisrev.github.io/assets/KotlinConf%20-%20Arrow\'s%202.0%20Trajectory/KotlinConf%20-%20Arrow\'s%202.0%20Trajectory%20-%20Simon.001.png","category":"slidedecks","tags":["core","slidedecks"],"link":"https://nomisrev.github.io/arrows-2-0-trajectory/","event":"Kotlin Conf"},"unlisted":false,"prevItem":{"title":"Typed Error Handling in Kotlin","permalink":"/community/blog/2023/04/17/typed-error-handling-in-kotlin"},"nextItem":{"title":"Arrow 1.2.0-RC Release Summary","permalink":"/community/blog/2023/04/04/arrow-1-2-0-rc-summary"}},"content":"A full transcript and the slides from [Simon Vergauwen\'s](https://twitter.com/vergauwen_simon) presentation from KotlinConf 2023 about the history of Arrow and where it\'s going."},{"id":"/2023/04/04/arrow-1-2-0-rc-summary","metadata":{"permalink":"/community/blog/2023/04/04/arrow-1-2-0-rc-summary","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-04-04-arrow-1-2-0-rc-summary.md","source":"@site/content/blog/2023-04-04-arrow-1-2-0-rc-summary.md","title":"Arrow 1.2.0-RC Release Summary","description":"We\'re excited to announce Arrow 1.2.0-RC alongside a new Arrow website. To briefly summarize, this release:","date":"2023-04-04T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.27,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 1.2.0-RC Release Summary","image":"https://xebia.com/wp-content/uploads/2023/04/arrow-1-2-0-rc-twitter.jpg","category":"articles","tags":["core","articles"],"link":"https://xebia.com/blog/arrow-1-2-0-rc-is-now-available/"},"unlisted":false,"prevItem":{"title":"Arrow 2.0\'s Trajectory","permalink":"/community/blog/2023/04/16/arrow-2-0-trajectory"},"nextItem":{"title":"Functional Fun in Kotlin","permalink":"/community/blog/2023/02/04/functional-fun-kotlin"}},"content":"We\'re excited to announce Arrow 1.2.0-RC alongside a new Arrow website. To briefly summarize, this release:\\n\\n- Introduces a brand new [typed errors](http://arrow-kt.io/learn/typed-errors/working-with-typed-errors/) module.\\n- Adds more options for [resilience](http://arrow-kt.io/learn/resilience/).\\n- Marks every function and type we intend to remove in 2.0 as `@Deprecated`.\\n\\nRead more details in the full [Arrow 1.2.0 release announcement](https://xebia.com/blog/arrow-1-2-0-rc-is-now-available/)."},{"id":"/2023/02/04/functional-fun-kotlin","metadata":{"permalink":"/community/blog/2023/02/04/functional-fun-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-02-04-functional-fun-kotlin.md","source":"@site/content/blog/2023-02-04-functional-fun-kotlin.md","title":"Functional Fun in Kotlin","description":"Simon Vergauwen shares why he thinks Kotlin is great language to do modern functional programming, and why he believes it\'s perhaps the best language to do modern mainstream (hardcore) functional programming.","date":"2023-02-04T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks"}],"readingTime":0.155,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Fun in Kotlin","image":"https://files.speakerdeck.com/presentations/717144e6f3f54fd7aca2215fff36c2b3/preview_slide_0.jpg","category":"slidedecks","tags":["core","slidedecks"],"link":"https://speakerdeck.com/nomisrev/functional-fun-in-kotlin","event":"FOSDEM"},"unlisted":false,"prevItem":{"title":"Arrow 1.2.0-RC Release Summary","permalink":"/community/blog/2023/04/04/arrow-1-2-0-rc-summary"},"nextItem":{"title":"CodelyTV Interview with Raul Raja","permalink":"/community/blog/2023/01/03/codelytv-interview"}},"content":"[Simon Vergauwen](https://twitter.com/vergauwen_simon) shares why he thinks Kotlin is great language to do modern functional programming, and why he believes it\'s perhaps the best language to do modern mainstream (hardcore) functional programming."},{"id":"/2023/01/03/codelytv-interview","metadata":{"permalink":"/community/blog/2023/01/03/codelytv-interview","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-01-03-codelytv-interview.md","source":"@site/content/blog/2023-01-03-codelytv-interview.md","title":"CodelyTV Interview with Raul Raja","description":"An interview with Arrow maintainer Ra\xfal Raja by Rafa G\xf3mez on CodelyTV.","date":"2023-01-03T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"CodelyTV Interview with Raul Raja","image":"https://img.youtube.com/vi/8WdprhzmQe4/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/8WdprhzmQe4"},"unlisted":false,"prevItem":{"title":"Functional Fun in Kotlin","permalink":"/community/blog/2023/02/04/functional-fun-kotlin"},"nextItem":{"title":"Actions as Data","permalink":"/community/blog/2022/12/01/actions-as-data"}},"content":"An interview with Arrow maintainer Ra\xfal Raja by Rafa G\xf3mez on CodelyTV."},{"id":"/2022/12/01/actions-as-data","metadata":{"permalink":"/community/blog/2022/12/01/actions-as-data","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-actions-as-data.md","source":"@site/content/blog/2022-12-01-actions-as-data.md","title":"Actions as Data","description":"A presentation by Alejandro Serrano at Advanced Kotlin Dev Day 2022.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.055,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Actions as Data","image":"https://img.youtube.com/vi/ujzZITapUwA/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/ujzZITapUwA"},"unlisted":false,"prevItem":{"title":"CodelyTV Interview with Raul Raja","permalink":"/community/blog/2023/01/03/codelytv-interview"},"nextItem":{"title":"Context Receivers: Kotlin\'s new secret sauce","permalink":"/community/blog/2022/12/01/context-receivers"}},"content":"A presentation by Alejandro Serrano at Advanced Kotlin Dev Day 2022."},{"id":"/2022/12/01/context-receivers","metadata":{"permalink":"/community/blog/2022/12/01/context-receivers","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-context-receivers.md","source":"@site/content/blog/2022-12-01-context-receivers.md","title":"Context Receivers: Kotlin\'s new secret sauce","description":"Alejandro Serrano\'s presentation from Advanced Kotlin Dev Day 2022 about context receivers.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Context Receivers: Kotlin\'s new secret sauce","image":"https://img.youtube.com/vi/2oiRCYnqhDs/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/2oiRCYnqhDs"},"unlisted":false,"prevItem":{"title":"Actions as Data","permalink":"/community/blog/2022/12/01/actions-as-data"},"nextItem":{"title":"Functional Error Handling - A Practical Approach","permalink":"/community/blog/2022/12/01/functional-error-handling"}},"content":"Alejandro Serrano\'s presentation from Advanced Kotlin Dev Day 2022 about context receivers."},{"id":"/2022/12/01/functional-error-handling","metadata":{"permalink":"/community/blog/2022/12/01/functional-error-handling","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-functional-error-handling.md","source":"@site/content/blog/2022-12-01-functional-error-handling.md","title":"Functional Error Handling - A Practical Approach","description":"A presentation by Bas de Groot at Advanced Kotlin Dev Day 2022.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Error Handling - A Practical Approach","image":"https://img.youtube.com/vi/T04ynq2IVFs/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/T04ynq2IVFs"},"unlisted":false,"prevItem":{"title":"Context Receivers: Kotlin\'s new secret sauce","permalink":"/community/blog/2022/12/01/context-receivers"},"nextItem":{"title":"Functional Flowing","permalink":"/community/blog/2022/12/01/functional-flowing"}},"content":"A presentation by Bas de Groot at Advanced Kotlin Dev Day 2022."},{"id":"/2022/12/01/functional-flowing","metadata":{"permalink":"/community/blog/2022/12/01/functional-flowing","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-functional-flowing.md","source":"@site/content/blog/2022-12-01-functional-flowing.md","title":"Functional Flowing","description":"Simon Vergauwen shows how to leverage KotlinX Flow to describe powerful programs and build pipelines to transform and manipulate data in an efficient streaming way.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.125,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Flowing","image":"https://img.youtube.com/vi/Mj9B0rhN1RE/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/Mj9B0rhN1RE"},"unlisted":false,"prevItem":{"title":"Functional Error Handling - A Practical Approach","permalink":"/community/blog/2022/12/01/functional-error-handling"},"nextItem":{"title":"Graceful Shutdown with Structured Concurrency","permalink":"/community/blog/2022/12/01/graceful-shutdown-structured-concurrency"}},"content":"Simon Vergauwen shows how to leverage KotlinX Flow to describe powerful programs and build pipelines to transform and manipulate data in an efficient streaming way."},{"id":"/2022/12/01/graceful-shutdown-structured-concurrency","metadata":{"permalink":"/community/blog/2022/12/01/graceful-shutdown-structured-concurrency","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-graceful-shutdown-structured-concurrency.md","source":"@site/content/blog/2022-12-01-graceful-shutdown-structured-concurrency.md","title":"Graceful Shutdown with Structured Concurrency","description":"A presentation by Simon Vergauwen at Advanced Kotlin Dev Day 2022.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.055,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Graceful Shutdown with Structured Concurrency","image":"https://img.youtube.com/vi/A69_t_oEP_E/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/A69_t_oEP_E"},"unlisted":false,"prevItem":{"title":"Functional Flowing","permalink":"/community/blog/2022/12/01/functional-flowing"},"nextItem":{"title":"Functional Programming in Kotlin: Exploring Arrow","permalink":"/community/blog/2022/07/01/exploring-arrow"}},"content":"A presentation by Simon Vergauwen at Advanced Kotlin Dev Day 2022."},{"id":"/2022/07/01/exploring-arrow","metadata":{"permalink":"/community/blog/2022/07/01/exploring-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-07-01-exploring-arrow.md","source":"@site/content/blog/2022-07-01-exploring-arrow.md","title":"Functional Programming in Kotlin: Exploring Arrow","description":"A presentation by Ties van de Veen at Voxxed Days Luxembourg 2022.","date":"2022-07-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Programming in Kotlin: Exploring Arrow","image":"https://img.youtube.com/vi/xxePZQlNyYY/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/xxePZQlNyYY"},"unlisted":false,"prevItem":{"title":"Graceful Shutdown with Structured Concurrency","permalink":"/community/blog/2022/12/01/graceful-shutdown-structured-concurrency"},"nextItem":{"title":"Turbocharging Kotlin: Arrow Analysis, Optics, and Meta","permalink":"/community/blog/2022/06/28/turbocharging-kotlin-talking-kotlin"}},"content":"A presentation by Ties van de Veen at Voxxed Days Luxembourg 2022."},{"id":"/2022/06/28/turbocharging-kotlin-talking-kotlin","metadata":{"permalink":"/community/blog/2022/06/28/turbocharging-kotlin-talking-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-06-28-turbocharging-kotlin-talking-kotlin.md","source":"@site/content/blog/2022-06-28-turbocharging-kotlin-talking-kotlin.md","title":"Turbocharging Kotlin: Arrow Analysis, Optics, and Meta","description":"Raul Raja, Simon Vergauwen, and Alejandro Serrano appeared on Talking Kotlin to chat about Arrow.","date":"2022-06-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"analysis","permalink":"/community/blog/tags/analysis"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.075,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Turbocharging Kotlin: Arrow Analysis, Optics, and Meta","image":"https://img.youtube.com/vi/tX4nLqcW2JA/maxresdefault.jpg","category":"videos","tags":["core","meta","optics","analysis","videos"],"link":"https://youtu.be/tX4nLqcW2JA"},"unlisted":false,"prevItem":{"title":"Functional Programming in Kotlin: Exploring Arrow","permalink":"/community/blog/2022/07/01/exploring-arrow"},"nextItem":{"title":"Arrow put on a big show at Kotlin Dev Day","permalink":"/community/blog/2022/06/14/arrow-kotlin-dev-day"}},"content":"Raul Raja, Simon Vergauwen, and Alejandro Serrano appeared on Talking Kotlin to chat about Arrow."},{"id":"/2022/06/14/arrow-kotlin-dev-day","metadata":{"permalink":"/community/blog/2022/06/14/arrow-kotlin-dev-day","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-06-14-arrow-kotlin-dev-day.md","source":"@site/content/blog/2022-06-14-arrow-kotlin-dev-day.md","title":"Arrow put on a big show at Kotlin Dev Day","description":"A recap of the attention Arrow received at Kotlin Dev Day.","date":"2022-06-14T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.055,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow put on a big show at Kotlin Dev Day","image":"https://www.47deg.com/assets/img/blog/featured_images/2022-06-13-arrow-put-on-big-show-at-kotlin-dev-day.jpg","category":"articles","tags":["core","fx","articles"],"link":"https://www.47deg.com/blog/arrow-put-on-big-show-at-kotlindevday/"},"unlisted":false,"prevItem":{"title":"Turbocharging Kotlin: Arrow Analysis, Optics, and Meta","permalink":"/community/blog/2022/06/28/turbocharging-kotlin-talking-kotlin"},"nextItem":{"title":"Building applications with Kotlin and Arrow.kt in style","permalink":"/community/blog/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style"}},"content":"A recap of the attention Arrow received at Kotlin Dev Day."},{"id":"/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style","metadata":{"permalink":"/community/blog/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-05-31-building-applications-with-kotlin-and-arrow-kt-in-style.md","source":"@site/content/blog/2022-05-31-building-applications-with-kotlin-and-arrow-kt-in-style.md","title":"Building applications with Kotlin and Arrow.kt in style","description":"A presentation by Simon Vergauwen presented on the official Kotlin YouTube channel.","date":"2022-05-31T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Building applications with Kotlin and Arrow.kt in style","image":"https://img.youtube.com/vi/g79A6HmbW5M/hqdefault.jpg","category":"videos","tags":["core","fx","videos"],"link":"https://youtu.be/g79A6HmbW5M"},"unlisted":false,"prevItem":{"title":"Arrow put on a big show at Kotlin Dev Day","permalink":"/community/blog/2022/06/14/arrow-kotlin-dev-day"},"nextItem":{"title":"Extending kotlinx.serialization functionality with Arrow Meta with Karin-Aleksandra Monoid","permalink":"/community/blog/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta"}},"content":"A presentation by Simon Vergauwen presented on the official Kotlin YouTube channel."},{"id":"/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta","metadata":{"permalink":"/community/blog/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-05-30-extending-kotlinx-serialization-functionality-arrow-meta.md","source":"@site/content/blog/2022-05-30-extending-kotlinx-serialization-functionality-arrow-meta.md","title":"Extending kotlinx.serialization functionality with Arrow Meta with Karin-Aleksandra Monoid","description":"Karin-Aleksandra Monoid provides an overview of Arrow Meta features.","date":"2022-05-30T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.045,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Extending kotlinx.serialization functionality with Arrow Meta with Karin-Aleksandra Monoid","image":"http://i3.ytimg.com/vi/eHSepXJPKZ0/hqdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://youtu.be/eHSepXJPKZ0","event":"Kotlin Dev Day"},"unlisted":false,"prevItem":{"title":"Building applications with Kotlin and Arrow.kt in style","permalink":"/community/blog/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style"},"nextItem":{"title":"Super-charge your build with Arrow Analysis by Alejandro Serrano Mena","permalink":"/community/blog/2022/05/30/super-charge-build-arrow-analysis"}},"content":"Karin-Aleksandra Monoid provides an overview of Arrow Meta features."},{"id":"/2022/05/30/super-charge-build-arrow-analysis","metadata":{"permalink":"/community/blog/2022/05/30/super-charge-build-arrow-analysis","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-05-30-super-charge-build-arrow-analysis.md","source":"@site/content/blog/2022-05-30-super-charge-build-arrow-analysis.md","title":"Super-charge your build with Arrow Analysis by Alejandro Serrano Mena","description":"Alejandro Serrano presents Arrow Analysis, a Kotlin compiler plug-in that does pre-and post-condition and type invariant checking at compile time.","date":"2022-05-30T00:00:00.000Z","tags":[{"label":"analysis","permalink":"/community/blog/tags/analysis"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.1,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Super-charge your build with Arrow Analysis by Alejandro Serrano Mena","image":"http://i3.ytimg.com/vi/yCZtnzTnpRA/hqdefault.jpg","category":"videos","tags":["analysis","videos"],"link":"https://youtu.be/yCZtnzTnpRA","event":"Kotlin Dev Day"},"unlisted":false,"prevItem":{"title":"Extending kotlinx.serialization functionality with Arrow Meta with Karin-Aleksandra Monoid","permalink":"/community/blog/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta"},"nextItem":{"title":"Functional programming in Kotlin: exploring Arrow by Ties Van de Ven","permalink":"/community/blog/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven"}},"content":"Alejandro Serrano presents Arrow Analysis, a Kotlin compiler plug-in that does pre-and post-condition and type invariant checking at compile time."},{"id":"/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven","metadata":{"permalink":"/community/blog/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-05-18-functional-programming-kotlin-exploring-arrow-ties-van-de-ven.md","source":"@site/content/blog/2022-05-18-functional-programming-kotlin-exploring-arrow-ties-van-de-ven.md","title":"Functional programming in Kotlin: exploring Arrow by Ties Van de Ven","description":"A talk by Ties van de Ven that shows how Arrow helps to unleash the full FP power of Kotlin.","date":"2022-05-18T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.1,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional programming in Kotlin: exploring Arrow by Ties Van de Ven","image":"http://i3.ytimg.com/vi/eFheAErqJzA/hqdefault.jpg","category":"videos","tags":["core","optics","videos"],"link":"https://youtu.be/eFheAErqJzA","event":"Devoxx UK"},"unlisted":false,"prevItem":{"title":"Super-charge your build with Arrow Analysis by Alejandro Serrano Mena","permalink":"/community/blog/2022/05/30/super-charge-build-arrow-analysis"},"nextItem":{"title":"Domain Model Validation In Kotlin: Part 4","permalink":"/community/blog/2022/03/31/domain-model-validation-in-kotlin-part-4"}},"content":"A talk by Ties van de Ven that shows how Arrow helps to unleash the full FP power of Kotlin."},{"id":"/2022/03/31/domain-model-validation-in-kotlin-part-4","metadata":{"permalink":"/community/blog/2022/03/31/domain-model-validation-in-kotlin-part-4","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-03-31-domain-model-validation-in-kotlin-part-4.md","source":"@site/content/blog/2022-03-31-domain-model-validation-in-kotlin-part-4.md","title":"Domain Model Validation In Kotlin: Part 4","description":"In this final part of the series, Tiberiu puts everything together in a small CLI application, using Arrow data types and computation blocks","date":"2022-03-31T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Domain Model Validation In Kotlin: Part 4","image":"https://miro.medium.com/max/1400/1*3jegLLY4GbGj71nauV2l_Q.png","category":"articles","tags":["core","articles"],"link":"https://tibtof.medium.com/domain-model-validation-in-kotlin-part-4-2462b334ca6c"},"unlisted":false,"prevItem":{"title":"Functional programming in Kotlin: exploring Arrow by Ties Van de Ven","permalink":"/community/blog/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven"},"nextItem":{"title":"Domain Model Validation In Kotlin: Part 3","permalink":"/community/blog/2022/03/10/domain-model-validation-in-kotlin-part-3"}},"content":"In this final part of the series, Tiberiu puts everything together in a small CLI application, using Arrow data types and computation blocks\\nto handle validation errors and exceptions in a unitary and composable way."},{"id":"/2022/03/10/domain-model-validation-in-kotlin-part-3","metadata":{"permalink":"/community/blog/2022/03/10/domain-model-validation-in-kotlin-part-3","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-03-10-domain-model-validation-in-kotlin-part-3.md","source":"@site/content/blog/2022-03-10-domain-model-validation-in-kotlin-part-3.md","title":"Domain Model Validation In Kotlin: Part 3","description":"In the third part of the series, Tiberiu Tofan explores multiple techniques of using a context when doing validations","date":"2022-03-10T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.2,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Domain Model Validation In Kotlin: Part 3","image":"https://miro.medium.com/max/1400/1*6RXLldOxvMR3nKi_k_wYTA.png","category":"articles","tags":["core","articles"],"link":"https://tibtof.medium.com/domain-model-validation-in-kotlin-part-3-96c3fd4af342"},"unlisted":false,"prevItem":{"title":"Domain Model Validation In Kotlin: Part 4","permalink":"/community/blog/2022/03/31/domain-model-validation-in-kotlin-part-4"},"nextItem":{"title":"Domain Model Validation In Kotlin: Part 2","permalink":"/community/blog/2022/03/03/domain-model-validation-in-kotlin-part-2"}},"content":"In the third part of the series, Tiberiu Tofan explores multiple techniques of using a context when doing validations \\nand how the context can be changed in the tests to simulate success or failure. All using just Kotlin standard library."},{"id":"/2022/03/03/domain-model-validation-in-kotlin-part-2","metadata":{"permalink":"/community/blog/2022/03/03/domain-model-validation-in-kotlin-part-2","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-03-03-domain-model-validation-in-kotlin-part-2.md","source":"@site/content/blog/2022-03-03-domain-model-validation-in-kotlin-part-2.md","title":"Domain Model Validation In Kotlin: Part 2","description":"In the second article in this series, Tiberiu Tofan writes how Validated type can be","date":"2022-03-03T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.195,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Domain Model Validation In Kotlin: Part 2","image":"https://miro.medium.com/max/1400/1*vf0byE6Kp5wGwmDqxRbUOg.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/@tibtof/domain-model-validation-in-kotlin-part-2-fb4726ef8f8d"},"unlisted":false,"prevItem":{"title":"Domain Model Validation In Kotlin: Part 3","permalink":"/community/blog/2022/03/10/domain-model-validation-in-kotlin-part-3"},"nextItem":{"title":"Domain Model Validation In Kotlin: Part 1","permalink":"/community/blog/2022/02/22/domain-model-validation-in-kotlin-part-1"}},"content":"In the second article in this series, Tiberiu Tofan writes how Validated type can be \\nused to validate multiple properties, accumulate the errors, apply individual \\nelement validations to lists of elements, and create rules that \\ndepend on numerous properties."},{"id":"/2022/02/22/domain-model-validation-in-kotlin-part-1","metadata":{"permalink":"/community/blog/2022/02/22/domain-model-validation-in-kotlin-part-1","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-02-22-domain-model-validation-in-kotlin-part-1.md","source":"@site/content/blog/2022-02-22-domain-model-validation-in-kotlin-part-1.md","title":"Domain Model Validation In Kotlin: Part 1","description":"In the first article in this series, Tiberiu Tofan describes his team\'s journey using Kotlin and Arrow for domain model validation,","date":"2022-02-22T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.16,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Domain Model Validation In Kotlin: Part 1","image":"https://miro.medium.com/max/1400/1*Xc0B4542z3WHiQ3DvLXcYg.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/@tibtof/domain-model-validation-in-kotlin-part-1-21fa44c60ef3"},"unlisted":false,"prevItem":{"title":"Domain Model Validation In Kotlin: Part 2","permalink":"/community/blog/2022/03/03/domain-model-validation-in-kotlin-part-2"},"nextItem":{"title":"Announcing Arrow Analysis - a Kotlin compiler plug-in","permalink":"/community/blog/2022/02/02/announcing-arrow-analysis"}},"content":"In the first article in this series, Tiberiu Tofan describes his team\'s journey using Kotlin and Arrow for domain model validation, \\nstarting by setting the domain model\'s foundation in a type-safe way."},{"id":"/2022/02/02/announcing-arrow-analysis","metadata":{"permalink":"/community/blog/2022/02/02/announcing-arrow-analysis","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-02-02-announcing-arrow-analysis.md","source":"@site/content/blog/2022-02-02-announcing-arrow-analysis.md","title":"Announcing Arrow Analysis - a Kotlin compiler plug-in","description":"Announcing Arrow Analysis - a Kotlin compiler plug-in.","date":"2022-02-02T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.04,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Announcing Arrow Analysis - a Kotlin compiler plug-in","image":"https://www.47deg.com/assets/img/blog/featured_images/2022-01-25-arrow-analysis-is-available.jpg","category":"articles","tags":["meta","articles"],"link":"https://www.47deg.com/blog/arrow-analysis-kotlin-compiler-plugin/"},"unlisted":false,"prevItem":{"title":"Domain Model Validation In Kotlin: Part 1","permalink":"/community/blog/2022/02/22/domain-model-validation-in-kotlin-part-1"},"nextItem":{"title":"Functional programming in Kotlin with Arrow","permalink":"/community/blog/2021/12/15/functional-programming-in-kotlin-with-arrow"}},"content":"Announcing Arrow Analysis - a Kotlin compiler plug-in."},{"id":"/2021/12/15/functional-programming-in-kotlin-with-arrow","metadata":{"permalink":"/community/blog/2021/12/15/functional-programming-in-kotlin-with-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-12-15-functional-programming-in-kotlin-with-arrow.md","source":"@site/content/blog/2021-12-15-functional-programming-in-kotlin-with-arrow.md","title":"Functional programming in Kotlin with Arrow","description":"A presentation by Simon Vergauwen and Alejandro Serrano presented on the official Kotlin YouTube channel.","date":"2021-12-15T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.075,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional programming in Kotlin with Arrow","image":"https://img.youtube.com/vi/IDMmmrRhUvQ/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/IDMmmrRhUvQ"},"unlisted":false,"prevItem":{"title":"Announcing Arrow Analysis - a Kotlin compiler plug-in","permalink":"/community/blog/2022/02/02/announcing-arrow-analysis"},"nextItem":{"title":"Functional programming in Kotlin: Exploring Arrow","permalink":"/community/blog/2021/11/30/functional-programming-kotlin-exploring-arrow"}},"content":"A presentation by Simon Vergauwen and Alejandro Serrano presented on the official Kotlin YouTube channel."},{"id":"/2021/11/30/functional-programming-kotlin-exploring-arrow","metadata":{"permalink":"/community/blog/2021/11/30/functional-programming-kotlin-exploring-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-11-30-functional-programming-kotlin-exploring-arrow.md","source":"@site/content/blog/2021-11-30-functional-programming-kotlin-exploring-arrow.md","title":"Functional programming in Kotlin: Exploring Arrow","description":"A talk by Ties van de Ven explaining how to use the Either monad in practice, and how to use Arrow Optics lenses.","date":"2021-11-30T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.115,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional programming in Kotlin: Exploring Arrow","image":"http://i3.ytimg.com/vi/Wojgv2MeMGU/hqdefault.jpg","category":"videos","tags":["core","optics","videos"],"link":"https://youtu.be/Wojgv2MeMGU","event":"Kotlin Dev Day Amsterdam"},"unlisted":false,"prevItem":{"title":"Functional programming in Kotlin with Arrow","permalink":"/community/blog/2021/12/15/functional-programming-in-kotlin-with-arrow"},"nextItem":{"title":"Arrow of Outrageous Error Handling","permalink":"/community/blog/2021/08/12/arrow-of-outrageous-error-handling"}},"content":"A talk by Ties van de Ven explaining how to use the Either monad in practice, and how to use Arrow Optics lenses."},{"id":"/2021/08/12/arrow-of-outrageous-error-handling","metadata":{"permalink":"/community/blog/2021/08/12/arrow-of-outrageous-error-handling","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-08-12-arrow-of-outrageous-error-handling.md","source":"@site/content/blog/2021-08-12-arrow-of-outrageous-error-handling.md","title":"Arrow of Outrageous Error Handling","description":"An Android Worldwide talk by David Rawson about error handling on Android using Arrow.","date":"2021-08-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow of Outrageous Error Handling","image":"http://i3.ytimg.com/vi/OiN79vpPM08/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/OiN79vpPM08","event":"Android Worldwide"},"unlisted":false,"prevItem":{"title":"Functional programming in Kotlin: Exploring Arrow","permalink":"/community/blog/2021/11/30/functional-programming-kotlin-exploring-arrow"},"nextItem":{"title":"Functional Domain Modeling in Kotlin - Validation","permalink":"/community/blog/2021/04/13/functional-domain-modeling-kotlin-validation"}},"content":"An Android Worldwide talk by David Rawson about error handling on Android using Arrow."},{"id":"/2021/04/13/functional-domain-modeling-kotlin-validation","metadata":{"permalink":"/community/blog/2021/04/13/functional-domain-modeling-kotlin-validation","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-04-13-functional-domain-modeling-kotlin-validation.md","source":"@site/content/blog/2021-04-13-functional-domain-modeling-kotlin-validation.md","title":"Functional Domain Modeling in Kotlin - Validation","description":"In part two of Functional Domain Modeling in Kotlin, Simon Vergauwen shows how to improve a domain with validation.","date":"2021-04-13T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.095,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Domain Modeling in Kotlin - Validation","image":"https://www.47deg.com/assets/img/blog/featured_images/2021-04-07-functional-domain-modeling-in-kotlin-validation.jpg","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/functional-domain-modeling-part-2/"},"unlisted":false,"prevItem":{"title":"Arrow of Outrageous Error Handling","permalink":"/community/blog/2021/08/12/arrow-of-outrageous-error-handling"},"nextItem":{"title":"Functional Domain Modeling in Kotlin","permalink":"/community/blog/2021/04/11/functional-domain-modeling-kotlin"}},"content":"In part two of Functional Domain Modeling in Kotlin, Simon Vergauwen shows how to improve a domain with validation."},{"id":"/2021/04/11/functional-domain-modeling-kotlin","metadata":{"permalink":"/community/blog/2021/04/11/functional-domain-modeling-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-04-11-functional-domain-modeling-kotlin.md","source":"@site/content/blog/2021-04-11-functional-domain-modeling-kotlin.md","title":"Functional Domain Modeling in Kotlin","description":"Learn how to leverage Functional Domain Modeling to fully utilize the Kotlin type system and prevent bugs.","date":"2021-04-11T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.085,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Domain Modeling in Kotlin","image":"https://www.47deg.com/assets/img/blog/featured_images/2021-02-05-functional-domain-modeling-in-kotlin.jpg","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/functional-domain-modeling/"},"unlisted":false,"prevItem":{"title":"Functional Domain Modeling in Kotlin - Validation","permalink":"/community/blog/2021/04/13/functional-domain-modeling-kotlin-validation"},"nextItem":{"title":"Your own custom Spring Data repository","permalink":"/community/blog/2021/04/11/your-own-custom-spring-data-repository"}},"content":"Learn how to leverage Functional Domain Modeling to fully utilize the Kotlin type system and prevent bugs."},{"id":"/2021/04/11/your-own-custom-spring-data-repository","metadata":{"permalink":"/community/blog/2021/04/11/your-own-custom-spring-data-repository","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-04-11-your-own-custom-spring-data-repository.md","source":"@site/content/blog/2021-04-11-your-own-custom-spring-data-repository.md","title":"Your own custom Spring Data repository","description":"How to integrate Spring Data Repository with Arrow.","date":"2021-04-11T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.04,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Your own custom Spring Data repository","image":"https://blog.frankel.ch/assets/resources/custom-spring-data-repository/spring-data.svg","category":"articles","tags":["core","articles"],"link":"https://blog.frankel.ch/custom-spring-data-repository/"},"unlisted":false,"prevItem":{"title":"Functional Domain Modeling in Kotlin","permalink":"/community/blog/2021/04/11/functional-domain-modeling-kotlin"},"nextItem":{"title":"Arrow 0.12.0 & 0.13.1 are now available","permalink":"/community/blog/2021/04/01/arrow-0-12-0-0-13-1-release"}},"content":"How to integrate Spring Data Repository with Arrow."},{"id":"/2021/04/01/arrow-0-12-0-0-13-1-release","metadata":{"permalink":"/community/blog/2021/04/01/arrow-0-12-0-0-13-1-release","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-04-01-arrow-0-12-0-0-13-1-release.md","source":"@site/content/blog/2021-04-01-arrow-0-12-0-0-13-1-release.md","title":"Arrow 0.12.0 & 0.13.1 are now available","description":"Arrow 0.12.0 & 0.13.1 are now available, featuring streamlining of the library for 1.0.0.","date":"2021-04-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 0.12.0 & 0.13.1 are now available","image":"https://www.47deg.com/assets/img/blog/featured_images/2021-03-30-arrow-0-13-1.jpg","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/arrow-0.13.0-release/"},"unlisted":false,"prevItem":{"title":"Your own custom Spring Data repository","permalink":"/community/blog/2021/04/11/your-own-custom-spring-data-repository"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Shiny Things","permalink":"/community/blog/2021/02/26/advanced-fp-enterprise-bee-shiny-things"}},"content":"Arrow 0.12.0 & 0.13.1 are now available, featuring streamlining of the library for 1.0.0."},{"id":"/2021/02/26/advanced-fp-enterprise-bee-shiny-things","metadata":{"permalink":"/community/blog/2021/02/26/advanced-fp-enterprise-bee-shiny-things","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-26-advanced-fp-enterprise-bee-shiny-things.md","source":"@site/content/blog/2021-02-26-advanced-fp-enterprise-bee-shiny-things.md","title":"Advanced FP for the Enterprise Bee: Shiny Things","description":"Garth Gilmour concludes his 8-part series introducing advanced FP concepts via Kotlin and Arrow.","date":"2021-02-26T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Shiny Things","image":"https://miro.medium.com/max/675/0*2D7qyemVVsa0Aldp.jpg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-shiny-things-770ae9c27472"},"unlisted":false,"prevItem":{"title":"Arrow 0.12.0 & 0.13.1 are now available","permalink":"/community/blog/2021/04/01/arrow-0-12-0-0-13-1-release"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: State","permalink":"/community/blog/2021/02/19/advanced-fp-enterprise-bee-state"}},"content":"Garth Gilmour concludes his 8-part series introducing advanced FP concepts via Kotlin and Arrow."},{"id":"/2021/02/19/advanced-fp-enterprise-bee-state","metadata":{"permalink":"/community/blog/2021/02/19/advanced-fp-enterprise-bee-state","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-19-advanced-fp-enterprise-bee-state.md","source":"@site/content/blog/2021-02-19-advanced-fp-enterprise-bee-state.md","title":"Advanced FP for the Enterprise Bee: State","description":"This is the seventh post in a series written by Garth Gilmour introducing advanced FP concepts via Kotlin and Arrow. This article explores the world of Monads, and, in particular, the State type.","date":"2021-02-19T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.165,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: State","image":"https://miro.medium.com/max/460/0*rMk9skNj5L-1E6cs","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-state-4f8fd2d8098b"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Shiny Things","permalink":"/community/blog/2021/02/26/advanced-fp-enterprise-bee-shiny-things"},"nextItem":{"title":"Hands-on Arrow","permalink":"/community/blog/2021/02/12/hands-on-arrow"}},"content":"This is the seventh post in a series written by Garth Gilmour introducing advanced FP concepts via Kotlin and Arrow. This article explores the world of Monads, and, in particular, the State type."},{"id":"/2021/02/12/hands-on-arrow","metadata":{"permalink":"/community/blog/2021/02/12/hands-on-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-12-hands-on-arrow.md","source":"@site/content/blog/2021-02-12-hands-on-arrow.md","title":"Hands-on Arrow","description":"A video from the meetup of the Google Developer Group based in Nuremberg with a presentation by Karin-Aleksandra Monoid about using Arrow.","date":"2021-02-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Hands-on Arrow","image":"http://i3.ytimg.com/vi/tkl9EaUMfm8/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/tkl9EaUMfm8?t=2136","event":"GDG Nuremberg"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: State","permalink":"/community/blog/2021/02/19/advanced-fp-enterprise-bee-state"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Optics","permalink":"/community/blog/2021/02/10/advanced-fp-enterprise-bee-optics"}},"content":"A video from the meetup of the Google Developer Group based in Nuremberg with a presentation by Karin-Aleksandra Monoid about using Arrow."},{"id":"/2021/02/10/advanced-fp-enterprise-bee-optics","metadata":{"permalink":"/community/blog/2021/02/10/advanced-fp-enterprise-bee-optics","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-10-advanced-fp-enterprise-bee-optics.md","source":"@site/content/blog/2021-02-10-advanced-fp-enterprise-bee-optics.md","title":"Advanced FP for the Enterprise Bee: Optics","description":"This is the sixth post in a series introducing advanced FP concepts via Kotlin and Arrow. This article covers Optics with Kotlin and Arrow.","date":"2021-02-10T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.12,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Optics","image":"https://miro.medium.com/max/700/1*7Q3EXosiX4YmLGYQWOllmQ.jpeg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-optics-2ccc444d409b"},"unlisted":false,"prevItem":{"title":"Hands-on Arrow","permalink":"/community/blog/2021/02/12/hands-on-arrow"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Typeclasses","permalink":"/community/blog/2021/02/05/advanced-fp-enterprise-bee-typeclasses"}},"content":"This is the sixth post in a series introducing advanced FP concepts via Kotlin and Arrow. This article covers Optics with Kotlin and Arrow."},{"id":"/2021/02/05/advanced-fp-enterprise-bee-typeclasses","metadata":{"permalink":"/community/blog/2021/02/05/advanced-fp-enterprise-bee-typeclasses","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-05-advanced-fp-enterprise-bee-typeclasses.md","source":"@site/content/blog/2021-02-05-advanced-fp-enterprise-bee-typeclasses.md","title":"Advanced FP for the Enterprise Bee: Typeclasses","description":"This fifth post in a series introduces advanced FP concepts via Kotlin and Arrow. This article introduces Typeclasses, and reviews a practical example of Typeclasses from the Arrow library.","date":"2021-02-05T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.145,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Typeclasses","image":"https://miro.medium.com/max/700/0*oOFUf_kkNWyHzS8Q.jpg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-typeclasses-2addc232ae23"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Optics","permalink":"/community/blog/2021/02/10/advanced-fp-enterprise-bee-optics"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Kleisli","permalink":"/community/blog/2021/01/29/advanced-fp-enterprise-bee-kleisli"}},"content":"This fifth post in a series introduces advanced FP concepts via Kotlin and Arrow. This article introduces Typeclasses, and reviews a practical example of Typeclasses from the Arrow library."},{"id":"/2021/01/29/advanced-fp-enterprise-bee-kleisli","metadata":{"permalink":"/community/blog/2021/01/29/advanced-fp-enterprise-bee-kleisli","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-29-advanced-fp-enterprise-bee-kleisli.md","source":"@site/content/blog/2021-01-29-advanced-fp-enterprise-bee-kleisli.md","title":"Advanced FP for the Enterprise Bee: Kleisli","description":"This fourth post in a series introduces advanced FP concepts via Kotlin and Arrow. This article looks at the Kleisli type.","date":"2021-01-29T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.105,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Kleisli","image":"https://miro.medium.com/max/397/1*ALuwNIY0UvXaBzk_zaBXTA.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-kleisli-1d0de0fa82d9"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Typeclasses","permalink":"/community/blog/2021/02/05/advanced-fp-enterprise-bee-typeclasses"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Higher Kinded Types","permalink":"/community/blog/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types"}},"content":"This fourth post in a series introduces advanced FP concepts via Kotlin and Arrow. This article looks at the Kleisli type."},{"id":"/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types","metadata":{"permalink":"/community/blog/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-22-advanced-fp-enterprise-bee-higher-kinded-types.md","source":"@site/content/blog/2021-01-22-advanced-fp-enterprise-bee-higher-kinded-types.md","title":"Advanced FP for the Enterprise Bee: Higher Kinded Types","description":"This third post in a series introduces advanced FP concepts via Kotlin and Arrow. This article shows the usefulness of Higher Kinded Types.","date":"2021-01-22T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.115,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Higher Kinded Types","image":"https://miro.medium.com/max/700/0*cXrhKidxYGGJABB1.jpg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-higher-kinded-types-c6742e24527"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Kleisli","permalink":"/community/blog/2021/01/29/advanced-fp-enterprise-bee-kleisli"},"nextItem":{"title":"FP concepts with Arrow","permalink":"/community/blog/2021/01/20/fp-concepts-with-arrow"}},"content":"This third post in a series introduces advanced FP concepts via Kotlin and Arrow. This article shows the usefulness of Higher Kinded Types."},{"id":"/2021/01/20/fp-concepts-with-arrow","metadata":{"permalink":"/community/blog/2021/01/20/fp-concepts-with-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-20-fp-concepts-with-arrow.md","source":"@site/content/blog/2021-01-20-fp-concepts-with-arrow.md","title":"FP concepts with Arrow","description":"A video from the Belfast Kotlin User Group with a presentation by Katie Levy and Shelby Cohen covering FP concepts with Arrow.","date":"2021-01-20T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"FP concepts with Arrow","image":"http://i3.ytimg.com/vi/IZlMQXLySz4/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/IZlMQXLySz4","event":"Belfast KUG"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Higher Kinded Types","permalink":"/community/blog/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Applicatives","permalink":"/community/blog/2021/01/15/advanced-fp-enterprise-bee-applicatives"}},"content":"A video from the Belfast Kotlin User Group with a presentation by Katie Levy and Shelby Cohen covering FP concepts with Arrow."},{"id":"/2021/01/15/advanced-fp-enterprise-bee-applicatives","metadata":{"permalink":"/community/blog/2021/01/15/advanced-fp-enterprise-bee-applicatives","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-15-advanced-fp-enterprise-bee-applicatives.md","source":"@site/content/blog/2021-01-15-advanced-fp-enterprise-bee-applicatives.md","title":"Advanced FP for the Enterprise Bee: Applicatives","description":"This second post in a series introduces advanced FP concepts via Kotlin and Arrow. This article takes a deep dive into Applicatives.","date":"2021-01-15T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Applicatives","image":"https://miro.medium.com/max/650/0*M1mKM3l9OCuW5bgC.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-applicatives-be76e4b6803c"},"unlisted":false,"prevItem":{"title":"FP concepts with Arrow","permalink":"/community/blog/2021/01/20/fp-concepts-with-arrow"},"nextItem":{"title":"Functional Android","permalink":"/community/blog/2021/01/13/functional-android"}},"content":"This second post in a series introduces advanced FP concepts via Kotlin and Arrow. This article takes a deep dive into Applicatives."},{"id":"/2021/01/13/functional-android","metadata":{"permalink":"/community/blog/2021/01/13/functional-android","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-13-functional-android.md","source":"@site/content/blog/2021-01-13-functional-android.md","title":"Functional Android","description":"In this talk from the January 13th, 2021 Kotlin London User Group meetup, Jorge Castillo shows how to seamlessly integrate the functional programming paradigm with our Android architecture to get the most out of both worlds.","date":"2021-01-13T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Android","image":"https://www.47deg.com/assets/img/events/featured_images/2021-01-13-kotlin-london-meetup.jpg","category":"videos","tags":["fx","videos"],"link":"https://youtu.be/XhijgrEG1tI","event":"Kotlin London"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Applicatives","permalink":"/community/blog/2021/01/15/advanced-fp-enterprise-bee-applicatives"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Traverse","permalink":"/community/blog/2021/01/08/advanced-fp-enterprise-bee-traverse"}},"content":"In this talk from the January 13th, 2021 Kotlin London User Group meetup, Jorge Castillo shows how to seamlessly integrate the functional programming paradigm with our Android architecture to get the most out of both worlds."},{"id":"/2021/01/08/advanced-fp-enterprise-bee-traverse","metadata":{"permalink":"/community/blog/2021/01/08/advanced-fp-enterprise-bee-traverse","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-08-advanced-fp-enterprise-bee-traverse.md","source":"@site/content/blog/2021-01-08-advanced-fp-enterprise-bee-traverse.md","title":"Advanced FP for the Enterprise Bee: Traverse","description":"This first post in a series introduces advanced FP concepts via Kotlin and Arrow. This article takes a deep dive into the Traverse operation.","date":"2021-01-08T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.12,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Traverse","image":"https://miro.medium.com/max/700/1*GAhKVPMXbQExcEhYho3XzQ.jpeg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-traverse-b5e4e8b7b8e4"},"unlisted":false,"prevItem":{"title":"Functional Android","permalink":"/community/blog/2021/01/13/functional-android"},"nextItem":{"title":"Roll your own Computation blocks in Kotlin","permalink":"/community/blog/2020/12/16/roll-your-own-computation-blocks-kotlin"}},"content":"This first post in a series introduces advanced FP concepts via Kotlin and Arrow. This article takes a deep dive into the Traverse operation."},{"id":"/2020/12/16/roll-your-own-computation-blocks-kotlin","metadata":{"permalink":"/community/blog/2020/12/16/roll-your-own-computation-blocks-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-12-16-roll-your-own-computation-blocks-kotlin.md","source":"@site/content/blog/2020-12-16-roll-your-own-computation-blocks-kotlin.md","title":"Roll your own Computation blocks in Kotlin","description":"Computation blocks empower library authors and users to build ad-hoc operators and DSLs over any data-type getting rid of API complexity and simplifying composition. In this talk, we will learn how we can build Computation blocks over Kotlin suspend functions & the Arrow Continuations library\'s reset / shift capabilities. We will demonstrate the composition of well known JVM data-types and patterns such as lists, futures, streams, and IOs, where callback chains can be simply replaced by a single","date":"2020-12-16T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.71,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Roll your own Computation blocks in Kotlin","image":"https://img.youtube.com/vi/0_zatebXMDU/hqdefault.jpg","category":"videos","tags":["core","fx","videos"],"link":"https://youtu.be/0_zatebXMDU","event":"Lambda Lille"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Traverse","permalink":"/community/blog/2021/01/08/advanced-fp-enterprise-bee-traverse"},"nextItem":{"title":"Fight Complexity with Functional Programming","permalink":"/community/blog/2020/11/19/fight-complexity-with-functional-programming"}},"content":"Computation blocks empower library authors and users to build ad-hoc operators and DSLs over any data-type getting rid of API complexity and simplifying composition. In this talk, we will learn how we can build Computation blocks over Kotlin suspend functions & the Arrow Continuations library\'s `reset` / `shift` capabilities. We will demonstrate the composition of well known JVM data-types and patterns such as lists, futures, streams, and IOs, where callback chains can be simply replaced by a single\\nsuspended operator. The Kotlin suspension system provides enough capabilities to implement delimited continuations allowing us to ignore methods such as `map` & `flatMap` on your favorite data-type in favor of direct imperative syntax. Leveraging Kotlin suspension & thinking of Continuations as \\"The Mother of all Monads\\", we will embark on this journey where we\'ll build and roll our own computation blocks with Arrow Continuations."},{"id":"/2020/11/19/fight-complexity-with-functional-programming","metadata":{"permalink":"/community/blog/2020/11/19/fight-complexity-with-functional-programming","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-11-19-fight-complexity-with-functional-programming.md","source":"@site/content/blog/2020-11-19-fight-complexity-with-functional-programming.md","title":"Fight Complexity with Functional Programming","description":"A Metric-driven approach to reduce Cognitive Complexity in a code base, using Functional Programming, demoed hands-on, by solving a complex real-world ubiquitous design challenge - REST API Bulk Request Validation, with an extensible Framework that separates what-to-do (Validations) from how-to-do (Validation Orchestration). Let\'s do a case study of a successful implementation done by our team in the world\'s largest SaaS org, Salesforce, using Kotlin and Arrow.","date":"2020-11-19T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.33,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Fight Complexity with Functional Programming","image":"https://img.youtube.com/vi/Dvr6gx4XaD8/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/Dvr6gx4XaD8","event":"All Things Open 2020"},"unlisted":false,"prevItem":{"title":"Roll your own Computation blocks in Kotlin","permalink":"/community/blog/2020/12/16/roll-your-own-computation-blocks-kotlin"},"nextItem":{"title":"Arrow Promoted to Adopt by Technology Radar","permalink":"/community/blog/2020/10/28/arrow-promoted-to-adopt"}},"content":"A Metric-driven approach to reduce Cognitive Complexity in a code base, using Functional Programming, demoed hands-on, by solving a complex real-world ubiquitous design challenge - REST API Bulk Request Validation, with an extensible Framework that separates what-to-do (Validations) from how-to-do (Validation Orchestration). Let\'s do a case study of a successful implementation done by our team in the world\'s largest SaaS org, Salesforce, using Kotlin and Arrow."},{"id":"/2020/10/28/arrow-promoted-to-adopt","metadata":{"permalink":"/community/blog/2020/10/28/arrow-promoted-to-adopt","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-10-28-arrow-promoted-to-adopt.md","source":"@site/content/blog/2020-10-28-arrow-promoted-to-adopt.md","title":"Arrow Promoted to Adopt by Technology Radar","description":"Arrow is promoted as the functional companion for Kotlin\'s standard library. Indeed, the package of ready-to-use higher-level abstractions delivered by Arrow has proven so useful that our teams now consider Arrow a sensible default when working with Kotlin. Recently, in preparation for the 1.0 release, the Arrow team introduced several changes, including the addition of new modules but also some deprecations and removals.","date":"2020-10-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.315,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Promoted to Adopt by Technology Radar","image":"https://static.thoughtworks.com/images/radar/2020-10/en/tech-radar-card.png","category":"articles","tags":["core","articles"],"link":"https://www.thoughtworks.com/radar/languages-and-frameworks/arrow"},"unlisted":false,"prevItem":{"title":"Fight Complexity with Functional Programming","permalink":"/community/blog/2020/11/19/fight-complexity-with-functional-programming"},"nextItem":{"title":"How to fix the pain of modifying Kotlin nested data classes","permalink":"/community/blog/2020/10/28/modifying-kotlin-nested-data-classes"}},"content":"Arrow is promoted as the functional companion for Kotlin\'s standard library. Indeed, the package of ready-to-use higher-level abstractions delivered by Arrow has proven so useful that our teams now consider Arrow a sensible default when working with Kotlin. Recently, in preparation for the 1.0 release, the Arrow team introduced several changes, including the addition of new modules but also some deprecations and removals."},{"id":"/2020/10/28/modifying-kotlin-nested-data-classes","metadata":{"permalink":"/community/blog/2020/10/28/modifying-kotlin-nested-data-classes","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-10-28-modifying-kotlin-nested-data-classes.md","source":"@site/content/blog/2020-10-28-modifying-kotlin-nested-data-classes.md","title":"How to fix the pain of modifying Kotlin nested data classes","description":"Lenses are not part of the Kotlin Standard Library yet, so we will need to use an Open Source library called Arrow-kt. Arrow-kt is a huge community effort to bring some of the missing functional programming features to Kotlin.","date":"2020-10-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.195,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"How to fix the pain of modifying Kotlin nested data classes","image":"https://i2.wp.com/ivanmorgillo.com/wp-content/uploads/2020/10/pexels-photo-712786.jpeg","category":"articles","tags":["core","articles"],"link":"https://ivanmorgillo.com/2020/10/28/how-to-fix-the-pain-of-modifying-kotlin-nested-data-classes/"},"unlisted":false,"prevItem":{"title":"Arrow Promoted to Adopt by Technology Radar","permalink":"/community/blog/2020/10/28/arrow-promoted-to-adopt"},"nextItem":{"title":"Technology Radar Promotes Arrow to \'Adopt\'","permalink":"/community/blog/2020/10/28/technology-radar-promotes-arrow"}},"content":"Lenses are not part of the Kotlin Standard Library yet, so we will need to use an Open Source library called Arrow-kt. Arrow-kt is a huge community effort to bring some of the missing functional programming features to Kotlin."},{"id":"/2020/10/28/technology-radar-promotes-arrow","metadata":{"permalink":"/community/blog/2020/10/28/technology-radar-promotes-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-10-28-technology-radar-promotes-arrow.md","source":"@site/content/blog/2020-10-28-technology-radar-promotes-arrow.md","title":"Technology Radar Promotes Arrow to \'Adopt\'","description":"Arrow has been promoted to \u201cAdopt\u201d by ThoughtWorks\u2019 technology guide Technology Radar.","date":"2020-10-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Technology Radar Promotes Arrow to \'Adopt\'","image":"https://www.47deg.com/assets/img/blog/featured_images/2020-10-28-arrow-promoted-to-adopt.jpg","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/arrow-promoted-to-adopt/"},"unlisted":false,"prevItem":{"title":"How to fix the pain of modifying Kotlin nested data classes","permalink":"/community/blog/2020/10/28/modifying-kotlin-nested-data-classes"},"nextItem":{"title":"Writing Kotlin Compiler Plugins with Arrow Meta","permalink":"/community/blog/2020/10/08/writing-kotlin-compiler-plugins-talk"}},"content":"Arrow has been promoted to \u201cAdopt\u201d by ThoughtWorks\u2019 technology guide *Technology Radar*."},{"id":"/2020/10/08/writing-kotlin-compiler-plugins-talk","metadata":{"permalink":"/community/blog/2020/10/08/writing-kotlin-compiler-plugins-talk","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-10-08-writing-kotlin-compiler-plugins-talk.md","source":"@site/content/blog/2020-10-08-writing-kotlin-compiler-plugins-talk.md","title":"Writing Kotlin Compiler Plugins with Arrow Meta","description":"Lean how to write and test compiler plugins and IDE plugins with Arrow Meta.","date":"2020-10-08T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Writing Kotlin Compiler Plugins with Arrow Meta","image":"https://codingwithmohit.com/assets/images/talks/writing_kotlin_compiler_plugins_with_arrow_meta.jpg","category":"videos","tags":["meta","videos"],"link":"https://www.droidcon.com/media-detail?video=470216591","event":"Droidcon EMEA 2020"},"unlisted":false,"prevItem":{"title":"Technology Radar Promotes Arrow to \'Adopt\'","permalink":"/community/blog/2020/10/28/technology-radar-promotes-arrow"},"nextItem":{"title":"Type Proofs and FP for the Kotlin Type System","permalink":"/community/blog/2020/06/16/type-proofs-fp-kotlin-talk"}},"content":"Lean how to write and test compiler plugins and IDE plugins with Arrow Meta."},{"id":"/2020/06/16/type-proofs-fp-kotlin-talk","metadata":{"permalink":"/community/blog/2020/06/16/type-proofs-fp-kotlin-talk","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-06-16-type-proofs-fp-kotlin-talk.md","source":"@site/content/blog/2020-06-16-type-proofs-fp-kotlin-talk.md","title":"Type Proofs and FP for the Kotlin Type System","description":"Type Proofs is a new compiler plugin built on Arrow Meta enabling new features in the Kotlin type system, such as Type Classes, Union Types, Type Refinements, and many other extensions that make Functional Programming easier in Kotlin.","date":"2020-06-16T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.495,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Type Proofs and FP for the Kotlin Type System","image":"https://img.youtube.com/vi/ETn_6LmMjho/hqdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://youtu.be/ETn_6LmMjho","event":"KTUG Munich June Meetup"},"unlisted":false,"prevItem":{"title":"Writing Kotlin Compiler Plugins with Arrow Meta","permalink":"/community/blog/2020/10/08/writing-kotlin-compiler-plugins-talk"},"nextItem":{"title":"Asynchronisme et hexagone en Kotlin avec ArrowKt","permalink":"/community/blog/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow"}},"content":"Type Proofs is a new compiler plugin built on Arrow Meta enabling new features in the Kotlin type system, such as Type Classes, Union Types, Type Refinements, and many other extensions that make Functional Programming easier in Kotlin.\\n\\nType Proofs propositions are expressed as extension functions that unlock new relationships between types ad-hoc whilst remaining fully compatible with subtype polymorphism and the existing inheritance type system.\\n\\nThis talk demonstrates some of the new features the Arrow team is introducing in Arrow at the type level and IDE and how others can benefit from them when building libraries and applications."},{"id":"/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow","metadata":{"permalink":"/community/blog/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-06-11-asynchronisme-et-hexagone-en-kotlin-avec-Arrow.md","source":"@site/content/blog/2020-06-11-asynchronisme-et-hexagone-en-kotlin-avec-Arrow.md","title":"Asynchronisme et hexagone en Kotlin avec ArrowKt","description":"J\'aime bien le DDD et surtout les architectures hexagonales. Avoir un domaine auto-portant et non coupl\xe9 \xe0 des blocs techniques comme Spring (ou autres) apporte beaucoup dans la testabilit\xe9 et l\'\xe9volutivit\xe9 de l\'application.","date":"2020-06-11T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.665,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Asynchronisme et hexagone en Kotlin avec ArrowKt","image":"https://img.youtube.com/vi/moJpV-BgezM/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/moJpV-BgezM","event":"Lambda Lille"},"unlisted":false,"prevItem":{"title":"Type Proofs and FP for the Kotlin Type System","permalink":"/community/blog/2020/06/16/type-proofs-fp-kotlin-talk"},"nextItem":{"title":"Arrow Fx: Functional Domain Modeling with Kotlin","permalink":"/community/blog/2020/06/05/functional-domain-modeling-kotlin"}},"content":"J\'aime bien le DDD et surtout les architectures hexagonales. Avoir un domaine auto-portant et non coupl\xe9 \xe0 des blocs techniques comme Spring (ou autres) apporte beaucoup dans la testabilit\xe9 et l\'\xe9volutivit\xe9 de l\'application.\\nLes mod\xe8les d\'asynchronismes (programmation r\xe9active, retard\xe9e, coroutines...) emp\xeachent la dissociation stricte de notre mod\xe8le m\xe9tier et de notre code infra dans un langage comme Kotlin.\\nOblig\xe9 d\'utiliser une lib de coroutine ou autre programmation reactive.\\nDeux solutions s\'offrent alors :\\n- D\xe9finir que les mod\xe8les d\'asynchronisme sont des invariants de notre domaine et accepter ce couplage\\n- Chercher comment mod\xe9liser notre domaine comme un ensemble de comportements asynchrones\\nDans ce talk nous allons voir comment r\xe9aliser la deuxi\xe8me solution en utilisant la librairie Arrow et son mod\xe8le conceptuel d\'asynchronisme pour nous permettre de d\xe9coupler notre domaine de toute logique d\'infrastructure."},{"id":"/2020/06/05/functional-domain-modeling-kotlin","metadata":{"permalink":"/community/blog/2020/06/05/functional-domain-modeling-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-06-05-functional-domain-modeling-kotlin.md","source":"@site/content/blog/2020-06-05-functional-domain-modeling-kotlin.md","title":"Arrow Fx: Functional Domain Modeling with Kotlin","description":"Arrow Fx is a purely functional concurrency framework for Kotlin\u2019s suspend system.","date":"2020-06-05T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.405,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Fx: Functional Domain Modeling with Kotlin","image":"https://img.youtube.com/vi/6sw8GAhUJz0/maxresdefault.jpg","category":"videos","tags":["fx","videos"],"link":"https://youtu.be/6sw8GAhUJz0","event":"Kotliners 2020"},"unlisted":false,"prevItem":{"title":"Asynchronisme et hexagone en Kotlin avec ArrowKt","permalink":"/community/blog/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow"},"nextItem":{"title":"Type Proofs and FP for the Kotlin Type System","permalink":"/community/blog/2020/05/27/type-proofs-fp-kotlin-talk"}},"content":"Arrow Fx is a purely functional concurrency framework for Kotlin\u2019s suspend system.\\n\\nIn this talk, we will learn how typed functional programming and functional domain modeling powered by Arrow Optics, Fx, and Meta can be applied to assemble powerful applications and architectures from small and simple building blocks.\\n\\nSimon and Raul will cover important topics and patterns such as optics, union types, refined types, type classes, automatic task cancellation, safe resource handling, and compare how Arrow Fx differs from KotlinX coroutines."},{"id":"/2020/05/27/type-proofs-fp-kotlin-talk","metadata":{"permalink":"/community/blog/2020/05/27/type-proofs-fp-kotlin-talk","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-05-27-type-proofs-fp-kotlin-talk.md","source":"@site/content/blog/2020-05-27-type-proofs-fp-kotlin-talk.md","title":"Type Proofs and FP for the Kotlin Type System","description":"Type Proofs is a new compiler plugin built on Arrow Meta enabling new features in the Kotlin type system, such as Type Classes, Union Types, Type Refinements, and many other extensions that make Functional Programming easier in Kotlin.","date":"2020-05-27T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.495,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Type Proofs and FP for the Kotlin Type System","image":"https://img.youtube.com/vi/lK80dPcsNUg/hqdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://www.youtube.com/watch?v=lK80dPcsNUg&t=353s","event":"Chicago Kotlin User Group Meetup"},"unlisted":false,"prevItem":{"title":"Arrow Fx: Functional Domain Modeling with Kotlin","permalink":"/community/blog/2020/06/05/functional-domain-modeling-kotlin"},"nextItem":{"title":"Android architectures with Arrow Fx","permalink":"/community/blog/2020/05/06/android-architectures-arrow-fx"}},"content":"Type Proofs is a new compiler plugin built on Arrow Meta enabling new features in the Kotlin type system, such as Type Classes, Union Types, Type Refinements, and many other extensions that make Functional Programming easier in Kotlin.\\n\\nType Proofs propositions are expressed as extension functions that unlock new relationships between types ad-hoc whilst remaining fully compatible with subtype polymorphism and the existing inheritance type system.\\n\\nThis talk demonstrates some of the new features the Arrow team is introducing in Arrow at the type level and IDE and how others can benefit from them when building libraries and applications."},{"id":"/2020/05/06/android-architectures-arrow-fx","metadata":{"permalink":"/community/blog/2020/05/06/android-architectures-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-05-06-android-architectures-arrow-fx.md","source":"@site/content/blog/2020-05-06-android-architectures-arrow-fx.md","title":"Android architectures with Arrow Fx","description":"May 2020 Online Kotlin Meetup","date":"2020-05-06T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.43,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Android architectures with Arrow Fx","image":"https://img.youtube.com/vi/r4D-oFd6wmY/maxresdefault.jpg","category":"videos","tags":["fx","videos"],"link":"https://youtu.be/r4D-oFd6wmY","event":"May 2020 Online Kotlin Meetup"},"unlisted":false,"prevItem":{"title":"Type Proofs and FP for the Kotlin Type System","permalink":"/community/blog/2020/05/27/type-proofs-fp-kotlin-talk"},"nextItem":{"title":"Writing a Kotlin Compiler Plugin with Arrow Meta","permalink":"/community/blog/2020/04/08/writing-compiler-plugin-with-with-arrow-meta"}},"content":"May 2020 Online Kotlin Meetup\\n\\nDaniel Montoya Ramos - Senior Software Engineer @47deg\\nAndroid Jetpack Compose\\n\\nDani will show a new way of building UI\'s in Android using Jetpack Compose, comparing Imperative vs Declarative approaches. He\'ll look at managing state changes, composing functions as well as some of the gotchas and wishes for the future.\\n\\nAlberto Ballano - Senior Software Engineer @47deg\\nAndroid architectures with Arrow Fx\\n\\nAlberto will talk about typical Android architectures, and how can they benefit from Functional Programming techniques available in Arrow."},{"id":"/2020/04/08/writing-compiler-plugin-with-with-arrow-meta","metadata":{"permalink":"/community/blog/2020/04/08/writing-compiler-plugin-with-with-arrow-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-04-08-writing-compiler-plugin-with-with-arrow-meta.md","source":"@site/content/blog/2020-04-08-writing-compiler-plugin-with-with-arrow-meta.md","title":"Writing a Kotlin Compiler Plugin with Arrow Meta","description":"Learn how to write and test the debuglog compiler plugin in Arrow Meta. Here is the compiler plugin debulog-arrow-meta explained in the article.","date":"2020-04-08T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.115,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Writing a Kotlin Compiler Plugin with Arrow Meta","image":"https://meta.arrow-kt.io/img/demos/hello-world-compiler-plugin.gif","category":"articles","tags":["meta","articles"],"link":"https://medium.com/@heyitsmohit/writing-kotlin-compiler-plugin-with-arrow-meta-cf7b3689aa3e"},"unlisted":false,"prevItem":{"title":"Android architectures with Arrow Fx","permalink":"/community/blog/2020/05/06/android-architectures-arrow-fx"},"nextItem":{"title":"Template-Oriented-Programming to Ship Faster, Part-1","permalink":"/community/blog/2020/04/06/template-oriented-programming-talk"}},"content":"Learn how to write and test the [debuglog](https://github.com/kevinmost/debuglog) compiler plugin in Arrow Meta. Here is the compiler plugin [debulog-arrow-meta](https://github.com/msya/debuglog-arrow-meta) explained in the article."},{"id":"/2020/04/06/template-oriented-programming-talk","metadata":{"permalink":"/community/blog/2020/04/06/template-oriented-programming-talk","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-04-06-template-oriented-programming-talk.md","source":"@site/content/blog/2020-04-06-template-oriented-programming-talk.md","title":"Template-Oriented-Programming to Ship Faster, Part-1","description":"Learn about the magic of Ad-hoc polymorphism using Arrow typeclasses with simple examples.","date":"2020-04-06T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.065,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Template-Oriented-Programming to Ship Faster, Part-1","image":"https://img.youtube.com/vi/_QBlKtUY6ac/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/_QBlKtUY6ac","event":"Kotlin User Group, Hyderabad, Online Meetup"},"unlisted":false,"prevItem":{"title":"Writing a Kotlin Compiler Plugin with Arrow Meta","permalink":"/community/blog/2020/04/08/writing-compiler-plugin-with-with-arrow-meta"},"nextItem":{"title":"Template-Oriented-Programming to Ship Faster","permalink":"/community/blog/2020/04/06/template-oriented-programming"}},"content":"Learn about the magic of Ad-hoc polymorphism using Arrow typeclasses with simple examples."},{"id":"/2020/04/06/template-oriented-programming","metadata":{"permalink":"/community/blog/2020/04/06/template-oriented-programming","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-04-06-template-oriented-programming.md","source":"@site/content/blog/2020-04-06-template-oriented-programming.md","title":"Template-Oriented-Programming to Ship Faster","description":"With a POC using Spring-fu + Kotlin + Arrow, let\'s Convert Monomorphic code (for common use-cases such as Auth, Validation) to Polymorphic reusable templates, to be reused among heterogeneous services built on different tech-stacks (blocking/non-blocking). This helps accelerate feature development.","date":"2020-04-06T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.2,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Template-Oriented-Programming to Ship Faster","image":"https://img.youtube.com/vi/_QBlKtUY6ac/maxresdefault.jpg","category":"articles","tags":["core","articles"],"link":"https://overfullstack.github.io/posts/top-with-ad-hoc-polymorphism/"},"unlisted":false,"prevItem":{"title":"Template-Oriented-Programming to Ship Faster, Part-1","permalink":"/community/blog/2020/04/06/template-oriented-programming-talk"},"nextItem":{"title":"Explaining the Arrow Android sample","permalink":"/community/blog/2020/04/01/explaining-arrow-android-sample"}},"content":"With a POC using Spring-fu + Kotlin + Arrow, let\'s Convert Monomorphic code (for common use-cases such as Auth, Validation) to Polymorphic reusable templates, to be reused among heterogeneous services built on different tech-stacks (blocking/non-blocking). This helps accelerate feature development."},{"id":"/2020/04/01/explaining-arrow-android-sample","metadata":{"permalink":"/community/blog/2020/04/01/explaining-arrow-android-sample","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-04-01-explaining-arrow-android-sample.md","source":"@site/content/blog/2020-04-01-explaining-arrow-android-sample.md","title":"Explaining the Arrow Android sample","description":"Arrow is an exciting development for Kotlin developers interested in functional programming and, more broadly, pushing the limits of the Kotlin compiler.","date":"2020-04-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Explaining the Arrow Android sample","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"articles","tags":["core","articles"],"link":"https://medium.com/default-to-open/explaining-the-arrow-android-sample-ee5c8bdfe88a"},"unlisted":false,"prevItem":{"title":"Template-Oriented-Programming to Ship Faster","permalink":"/community/blog/2020/04/06/template-oriented-programming"},"nextItem":{"title":"IO integration with kotlinx.coroutines","permalink":"/community/blog/2020/03/02/io-integration-kotlinx-coroutines"}},"content":"Arrow is an exciting development for Kotlin developers interested in functional programming and, more broadly, pushing the limits of the Kotlin compiler."},{"id":"/2020/03/02/io-integration-kotlinx-coroutines","metadata":{"permalink":"/community/blog/2020/03/02/io-integration-kotlinx-coroutines","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-03-02-io-integration-kotlinx-coroutines.md","source":"@site/content/blog/2020-03-02-io-integration-kotlinx-coroutines.md","title":"IO integration with kotlinx.coroutines","description":"This article showcases the brand new Arrow integration module for KotlinX Coroutines included in the Arrow 0.10.5 release.","date":"2020-03-02T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.09,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"IO integration with kotlinx.coroutines","image":"https://www.47deg.com/assets/img/blog/featured_images/2020-03-26-io-integration-kotlinx-coroutines.jpg","category":"articles","tags":["fx","articles"],"link":"https://www.47deg.com/blog/arrow-kotlinx-integration/"},"unlisted":false,"prevItem":{"title":"Explaining the Arrow Android sample","permalink":"/community/blog/2020/04/01/explaining-arrow-android-sample"},"nextItem":{"title":"FP with Kotlin/Arrow: Monad Comprehensions & Parallel Processing","permalink":"/community/blog/2020/02/26/fp-with-kotlin-arrow"}},"content":"This article showcases the brand new Arrow integration module for KotlinX Coroutines included in the Arrow 0.10.5 release."},{"id":"/2020/02/26/fp-with-kotlin-arrow","metadata":{"permalink":"/community/blog/2020/02/26/fp-with-kotlin-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-02-26-fp-with-kotlin-arrow.md","source":"@site/content/blog/2020-02-26-fp-with-kotlin-arrow.md","title":"FP with Kotlin/Arrow: Monad Comprehensions & Parallel Processing","description":"Arrow has multiple libraries available for functional programming. In this talk we\'ll focus on Arrow FX and learn how to handle IO in a functional way with an introduction to monadic composition. Then we\'ll examine how to compose monads in a cleaner fashion with Arrow FX\'s monad comprehensions. Finally, we\'ll take a look at how to parallelize IO monads with parallel map strategies.","date":"2020-02-26T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.315,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"FP with Kotlin/Arrow: Monad Comprehensions & Parallel Processing","image":"https://img.youtube.com/vi/nAtzuIRryuE/maxresdefault.jpg","category":"videos","tags":["fx","videos"],"link":"https://youtu.be/nAtzuIRryuE"},"unlisted":false,"prevItem":{"title":"IO integration with kotlinx.coroutines","permalink":"/community/blog/2020/03/02/io-integration-kotlinx-coroutines"},"nextItem":{"title":"What could possibly go wrong? - A safer programming with Arrow","permalink":"/community/blog/2020/02/26/safer-programming-with-arrow"}},"content":"Arrow has multiple libraries available for functional programming. In this talk we\'ll focus on Arrow FX and learn how to handle IO in a functional way with an introduction to monadic composition. Then we\'ll examine how to compose monads in a cleaner fashion with Arrow FX\'s monad comprehensions. Finally, we\'ll take a look at how to parallelize IO monads with parallel map strategies."},{"id":"/2020/02/26/safer-programming-with-arrow","metadata":{"permalink":"/community/blog/2020/02/26/safer-programming-with-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-02-26-safer-programming-with-arrow.md","source":"@site/content/blog/2020-02-26-safer-programming-with-arrow.md","title":"What could possibly go wrong? - A safer programming with Arrow","description":"Your Kotlin app grabs data from an API, transforms it and saves the processed data in a database. However, there are so many things that could go wrong at runtime treat your impure functions as computations with context, pass them around just like other values, and make the necessary unsafe invocation from a single point of your app, your main function.","date":"2020-02-26T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.785,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"What could possibly go wrong? - A safer programming with Arrow","image":"https://img.youtube.com/vi/C9SmleSSeGk/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/C9SmleSSeGk"},"unlisted":false,"prevItem":{"title":"FP with Kotlin/Arrow: Monad Comprehensions & Parallel Processing","permalink":"/community/blog/2020/02/26/fp-with-kotlin-arrow"},"nextItem":{"title":"Kotlin Functional Programming: Cleaner Composition with Monad Comprehensions in Arrow Fx","permalink":"/community/blog/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx"}},"content":"Your Kotlin app grabs data from an API, transforms it and saves the processed data in a database. However, there are so many things that could go wrong at runtime: the API might be inaccessible, the data is not what you expected or the data can\'t be persisted in the database. You can start adding try catch blocks to your function in your objects, but there is a better way to do it: treat your impure functions as computations with context, pass them around just like other values, and make the necessary unsafe invocation from a single point of your app, your main function.\\n\\nThis talk will walk you through the core functional concepts of Arrow, you will learn how Some, Either and even IO are functor, applicative and monad. You can use the code example from this talk as a starting point for your Arrow-learning, to write safer, simpler and more elegant functional code in Kotlin."},{"id":"/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx","metadata":{"permalink":"/community/blog/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-01-29-cleaner-composition-with-monad-comprehensions-arrow-fx.md","source":"@site/content/blog/2020-01-29-cleaner-composition-with-monad-comprehensions-arrow-fx.md","title":"Kotlin Functional Programming: Cleaner Composition with Monad Comprehensions in Arrow Fx","description":"Learn how to write cleaner monadic composition in Kotlin with Arrow\u2019s monad comprehensions, available in Arrow FX.","date":"2020-01-29T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.085,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin Functional Programming: Cleaner Composition with Monad Comprehensions in Arrow Fx","image":"https://raw.githubusercontent.com/arrow-kt/arrow-site/master/docs/img/fx/arrow-fx-brand-sidebar.svg?sanitize=true","category":"articles","tags":["fx","articles"],"link":"https://lambda.show/blog/arrow-io-monad-comprehensions-cleaner-monadic-composition"},"unlisted":false,"prevItem":{"title":"What could possibly go wrong? - A safer programming with Arrow","permalink":"/community/blog/2020/02/26/safer-programming-with-arrow"},"nextItem":{"title":"Kotlin Functional Programming: Monads & Composition with Arrow Fx","permalink":"/community/blog/2020/01/29/monads-and-composition-with-arrow-fx"}},"content":"Learn how to write cleaner monadic composition in Kotlin with Arrow\u2019s monad comprehensions, available in Arrow FX."},{"id":"/2020/01/29/monads-and-composition-with-arrow-fx","metadata":{"permalink":"/community/blog/2020/01/29/monads-and-composition-with-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-01-29-monads-and-composition-with-arrow-fx.md","source":"@site/content/blog/2020-01-29-monads-and-composition-with-arrow-fx.md","title":"Kotlin Functional Programming: Monads & Composition with Arrow Fx","description":"Arrow is a library created by folks over at a company called 47 degrees . In a nutshell, Arrow brings a slew of functional programming features to Kotlin. It is heavily inspired by Scala and Haskell, and emphasizes a lot of the concepts that those languages started","date":"2020-01-29T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.235,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin Functional Programming: Monads & Composition with Arrow Fx","image":"https://raw.githubusercontent.com/arrow-kt/arrow-site/master/docs/img/fx/arrow-fx-brand-sidebar.svg?sanitize=true","category":"articles","tags":["fx","articles"],"link":"https://lambda.show/blog/arrow-io-monad"},"unlisted":false,"prevItem":{"title":"Kotlin Functional Programming: Cleaner Composition with Monad Comprehensions in Arrow Fx","permalink":"/community/blog/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx"},"nextItem":{"title":"Kotlin Functional Programming: Parallel Processing The Functional Way with Arrow Fx","permalink":"/community/blog/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx"}},"content":"Arrow is a library created by folks over at a company called 47 degrees . In a nutshell, Arrow brings a slew of functional programming features to Kotlin. It is heavily inspired by Scala and Haskell, and emphasizes a lot of the concepts that those languages started"},{"id":"/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx","metadata":{"permalink":"/community/blog/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-01-29-parallel-processing-the-functional-way-with-arrow-fx.md","source":"@site/content/blog/2020-01-29-parallel-processing-the-functional-way-with-arrow-fx.md","title":"Kotlin Functional Programming: Parallel Processing The Functional Way with Arrow Fx","description":"Learn how to handle parallel processing in Kotlin with Arrow IO monads.","date":"2020-01-29T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin Functional Programming: Parallel Processing The Functional Way with Arrow Fx","image":"https://raw.githubusercontent.com/arrow-kt/arrow-site/master/docs/img/fx/arrow-fx-brand-sidebar.svg?sanitize=true","category":"articles","tags":["fx","articles"],"link":"https://lambda.show/blog/arrow-io-parallel"},"unlisted":false,"prevItem":{"title":"Kotlin Functional Programming: Monads & Composition with Arrow Fx","permalink":"/community/blog/2020/01/29/monads-and-composition-with-arrow-fx"},"nextItem":{"title":"Arrow Comonad Approach for GameOfLife with Android Compose","permalink":"/community/blog/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife"}},"content":"Learn how to handle parallel processing in Kotlin with Arrow IO monads."},{"id":"/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife","metadata":{"permalink":"/community/blog/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-01-14-Arrow-Comonad-Android-Compose-gameOfLife.md","source":"@site/content/blog/2020-01-14-Arrow-Comonad-Android-Compose-gameOfLife.md","title":"Arrow Comonad Approach for GameOfLife with Android Compose","description":"The purpose of this article is complement the bow + SwifUi solution for the game of live we can find here https://www.47deg.com/blog/conway-swift/ with the arrow + compose version.","date":"2020-01-14T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.14,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Comonad Approach for GameOfLife with Android Compose","image":"https://user-images.githubusercontent.com/39838885/72436632-a95c6380-377f-11ea-8a31-fe0c05d49946.gif","category":"articles","tags":["fx","articles"],"link":"https://github.com/matiaslev/ArrowComposeLifeGame/tree/master"},"unlisted":false,"prevItem":{"title":"Kotlin Functional Programming: Parallel Processing The Functional Way with Arrow Fx","permalink":"/community/blog/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx"},"nextItem":{"title":"Kotlin coroutines with arrow-fx","permalink":"/community/blog/2019/12/15/Kotlin-coroutines-with-arrow-fx"}},"content":"The purpose of this article is complement the bow + SwifUi solution for the game of live we can find here https://www.47deg.com/blog/conway-swift/ with the arrow + compose version."},{"id":"/2019/12/15/Kotlin-coroutines-with-arrow-fx","metadata":{"permalink":"/community/blog/2019/12/15/Kotlin-coroutines-with-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-12-15-Kotlin-coroutines-with-arrow-fx.md","source":"@site/content/blog/2019-12-15-Kotlin-coroutines-with-arrow-fx.md","title":"Kotlin coroutines with arrow-fx","description":"The purpose of this article is to summarize the approaches from questions at Slack about the usage of Either, Option and other datatypes and to give a tour of arrow-fx usage and APIs.","date":"2019-12-15T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.165,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin coroutines with arrow-fx","image":"https://www.pacoworks.com/content/images/2016/05/banner_v2.png","category":"articles","tags":["fx","articles"],"link":"https://www.pacoworks.com/2019/12/15/kotlin-coroutines-with-arrow-fx/"},"unlisted":false,"prevItem":{"title":"Arrow Comonad Approach for GameOfLife with Android Compose","permalink":"/community/blog/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife"},"nextItem":{"title":"Conway\'s Game of Life using Kotlin and Arrow","permalink":"/community/blog/2019/12/12/GOL-using-Kotlin-and-Arrow"}},"content":"The purpose of this article is to summarize the approaches from questions at Slack about the usage of Either, Option and other datatypes and to give a tour of arrow-fx usage and APIs."},{"id":"/2019/12/12/GOL-using-Kotlin-and-Arrow","metadata":{"permalink":"/community/blog/2019/12/12/GOL-using-Kotlin-and-Arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-12-12-GOL-using-Kotlin-and-Arrow.md","source":"@site/content/blog/2019-12-12-GOL-using-Kotlin-and-Arrow.md","title":"Conway\'s Game of Life using Kotlin and Arrow","description":"An article of a series on Functional Programming solutions for the Global Day of Coderetreat challenge. In this case, it shows an approach for it using Kotlin and Functional Programming provided by the Arrow library.","date":"2019-12-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Conway\'s Game of Life using Kotlin and Arrow","image":"https://www.47deg.com/assets/img/blog/featured_images/2019-12-12-game-of-life-kotlin.jpg","category":"articles","tags":["core","fx","articles"],"link":"https://www.47deg.com/blog/conway-kotlin/"},"unlisted":false,"prevItem":{"title":"Kotlin coroutines with arrow-fx","permalink":"/community/blog/2019/12/15/Kotlin-coroutines-with-arrow-fx"},"nextItem":{"title":"Keep insisting - Arrow Meta","permalink":"/community/blog/2019/12/06/kotlinconf-arrow-meta"}},"content":"An article of a series on Functional Programming solutions for the Global Day of Coderetreat challenge. In this case, it shows an approach for it using Kotlin and Functional Programming provided by the Arrow library."},{"id":"/2019/12/06/kotlinconf-arrow-meta","metadata":{"permalink":"/community/blog/2019/12/06/kotlinconf-arrow-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-12-06-kotlinconf-arrow-meta.md","source":"@site/content/blog/2019-12-06-kotlinconf-arrow-meta.md","title":"Keep insisting - Arrow Meta","description":"Arrow Meta is a library that empowers library and application authors with the ability to write plugins for the Kotlin compiler. Compiler plugins have access to all compiler phases and can intercept and modify the AST, descriptors, and IR intermediate lang for bytecode generation.","date":"2019-12-06T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.22,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Keep insisting - Arrow Meta","image":"https://img.youtube.com/vi/n9smQNxUyBI/maxresdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://youtu.be/n9smQNxUyBI","event":"KotlinConf, Copenhagen"},"unlisted":false,"prevItem":{"title":"Conway\'s Game of Life using Kotlin and Arrow","permalink":"/community/blog/2019/12/12/GOL-using-Kotlin-and-Arrow"},"nextItem":{"title":"Arrow Fx & Arrow Meta - Functional Programming for the masses","permalink":"/community/blog/2019/11/27/functional-jvm-arrow-fx-meta"}},"content":"Arrow Meta is a library that empowers library and application authors with the ability to write plugins for the Kotlin compiler. Compiler plugins have access to all compiler phases and can intercept and modify the AST, descriptors, and IR intermediate lang for bytecode generation."},{"id":"/2019/11/27/functional-jvm-arrow-fx-meta","metadata":{"permalink":"/community/blog/2019/11/27/functional-jvm-arrow-fx-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-11-27-functional-jvm-arrow-fx-meta.md","source":"@site/content/blog/2019-11-27-functional-jvm-arrow-fx-meta.md","title":"Arrow Fx & Arrow Meta - Functional Programming for the masses","description":"In this meetup we discuss the new features of Arrow Fx to write \u201ceffectful\u201d programs with an emphasis on simple and declarative programming for everyone.","date":"2019-11-27T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.235,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Fx & Arrow Meta - Functional Programming for the masses","image":"https://img.youtube.com/vi/DaognWtZCbs/maxresdefault.jpg","category":"videos","tags":["meta","fx","videos"],"link":"https://www.youtube.com/watch?v=DaognWtZCbs","event":"Functional JVM Meetup, Prague"},"unlisted":false,"prevItem":{"title":"Keep insisting - Arrow Meta","permalink":"/community/blog/2019/12/06/kotlinconf-arrow-meta"},"nextItem":{"title":"Arrow Meta - Enabling Functional Programming in the Kotlin Compiler","permalink":"/community/blog/2019/10/18/lambda-world-arrow-meta"}},"content":"In this meetup we discuss the new features of Arrow Fx to write \u201ceffectful\u201d programs with an emphasis on simple and declarative programming for everyone.\\nAdditionally, we see how Arrow Meta works and how we can use it to improve the ergonomics of Functional Programming in Kotlin."},{"id":"/2019/10/18/lambda-world-arrow-meta","metadata":{"permalink":"/community/blog/2019/10/18/lambda-world-arrow-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-10-18-lambda-world-arrow-meta.md","source":"@site/content/blog/2019-10-18-lambda-world-arrow-meta.md","title":"Arrow Meta - Enabling Functional Programming in the Kotlin Compiler","description":"Arrow Meta is a library that empowers library and application authors with the ability to write plugins for the Kotlin compiler. Compiler plugins have access to all compiler phases and can intercept and modify the AST, descriptors, and IR intermediate lang for bytecode generation.","date":"2019-10-18T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.22,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Meta - Enabling Functional Programming in the Kotlin Compiler","image":"https://img.youtube.com/vi/WKR384ZeBgk/maxresdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://www.youtube.com/watch?v=WKR384ZeBgk","event":"Lambda World, C\xe1diz, Spain"},"unlisted":false,"prevItem":{"title":"Arrow Fx & Arrow Meta - Functional Programming for the masses","permalink":"/community/blog/2019/11/27/functional-jvm-arrow-fx-meta"},"nextItem":{"title":"Kotlin and Arrow: the functional way","permalink":"/community/blog/2019/08/08/kotlin-and-arrow-the-functional-way"}},"content":"Arrow Meta is a library that empowers library and application authors with the ability to write plugins for the Kotlin compiler. Compiler plugins have access to all compiler phases and can intercept and modify the AST, descriptors, and IR intermediate lang for bytecode generation."},{"id":"/2019/08/08/kotlin-and-arrow-the-functional-way","metadata":{"permalink":"/community/blog/2019/08/08/kotlin-and-arrow-the-functional-way","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-08-08-kotlin-and-arrow-the-functional-way.md","source":"@site/content/blog/2019-08-08-kotlin-and-arrow-the-functional-way.md","title":"Kotlin and Arrow: the functional way","description":"Kotlin is a great language for developing server-side applications; it\'s an object-oriented language and also a functional one, supporting features such as function types, lambdas or higher order functions. But...is this enough to switch completely from an imperative paradigm to a functional paradigm?","date":"2019-08-08T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.33,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin and Arrow: the functional way","image":"https://pbs.twimg.com/media/D8xN-4jWkAAceCW.jpg","category":"videos","tags":["core","videos"],"link":"https://thoughtworks.wistia.com/medias/ifra1gzrho","event":"xConf, Barcelona, Spain"},"unlisted":false,"prevItem":{"title":"Arrow Meta - Enabling Functional Programming in the Kotlin Compiler","permalink":"/community/blog/2019/10/18/lambda-world-arrow-meta"},"nextItem":{"title":"Effect polymorphism with Arrow FX","permalink":"/community/blog/2019/07/22/polymorphic-fx"}},"content":"Kotlin is a great language for developing server-side applications; it\'s an object-oriented language and also a functional one, supporting features such as function types, lambdas or higher order functions. But...is this enough to switch completely from an imperative paradigm to a functional paradigm?\\n\\nIn this talk by Noe Luaces, we\'ll see how features from Arrow library completes Kotlin in order to follow a pure functional way."},{"id":"/2019/07/22/polymorphic-fx","metadata":{"permalink":"/community/blog/2019/07/22/polymorphic-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-07-22-polymorphic-fx.md","source":"@site/content/blog/2019-07-22-polymorphic-fx.md","title":"Effect polymorphism with Arrow FX","description":"Wonder how to handle side effects in a very clean way while abstracting the real effect implementation? #Arrow #FX provides an easy way to do this, without the burden of Higher-Kinded Types.","date":"2019-07-22T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.16,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Effect polymorphism with Arrow FX","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"articles","tags":["fx","articles"],"link":"https://www.msec.it/blog/effect-polymorphism-with-arrow-fx/"},"unlisted":false,"prevItem":{"title":"Kotlin and Arrow: the functional way","permalink":"/community/blog/2019/08/08/kotlin-and-arrow-the-functional-way"},"nextItem":{"title":"Self-contained example of testing with modules and Arrow FX","permalink":"/community/blog/2019/07/05/testing-with-modules"}},"content":"Wonder how to handle side effects in a very clean way while abstracting the real effect implementation? #Arrow #FX provides an easy way to do this, without the burden of Higher-Kinded Types."},{"id":"/2019/07/05/testing-with-modules","metadata":{"permalink":"/community/blog/2019/07/05/testing-with-modules","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-07-05-testing-with-modules.md","source":"@site/content/blog/2019-07-05-testing-with-modules.md","title":"Self-contained example of testing with modules and Arrow FX","description":"This post shows a porting with Kotlin and Arrow FX of a self-contained testing example with Scala ZIO","date":"2019-07-05T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.09,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Self-contained example of testing with modules and Arrow FX","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"articles","tags":["core","fx","articles"],"link":"https://www.msec.it/blog/self-contained-example-of-testing-with-modules-and-arrow-fx/"},"unlisted":false,"prevItem":{"title":"Effect polymorphism with Arrow FX","permalink":"/community/blog/2019/07/22/polymorphic-fx"},"nextItem":{"title":"Modular functional programming with Kotlin","permalink":"/community/blog/2019/07/02/modular-app-kotlin"}},"content":"This post shows a porting with Kotlin and Arrow FX of a self-contained testing example with Scala ZIO"},{"id":"/2019/07/02/modular-app-kotlin","metadata":{"permalink":"/community/blog/2019/07/02/modular-app-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-07-02-modular-app-kotlin.md","source":"@site/content/blog/2019-07-02-modular-app-kotlin.md","title":"Modular functional programming with Kotlin","description":"This post proposes a possible solution in order to structure and compose a pure functional Kotlin application, in order to better manage and decouple modules, get simpler tests and manage the Dependency Injection at compile time.","date":"2019-07-02T00:00:00.000Z","tags":[],"readingTime":0.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Modular functional programming with Kotlin","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"articles","tag":["core","articles"],"link":"https://www.msec.it/blog/modular-functional-programming-composition-with-kotlin/"},"unlisted":false,"prevItem":{"title":"Self-contained example of testing with modules and Arrow FX","permalink":"/community/blog/2019/07/05/testing-with-modules"},"nextItem":{"title":"ArrowFx: Functional Programming for the masses","permalink":"/community/blog/2019/06/07/kotliners-arrow-fx"}},"content":"This post proposes a possible solution in order to structure and compose a pure functional Kotlin application, in order to better manage and decouple modules, get simpler tests and manage the Dependency Injection at compile time."},{"id":"/2019/06/07/kotliners-arrow-fx","metadata":{"permalink":"/community/blog/2019/06/07/kotliners-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-06-07-kotliners-arrow-fx.md","source":"@site/content/blog/2019-06-07-kotliners-arrow-fx.md","title":"ArrowFx: Functional Programming for the masses","description":"In this talk we recap about the imminent future of Functional Programming in Kotlin. With ArrowFx you are able to encode \u201ceffectful\u201d programs in a controlled way following the FP principles through a direct syntax. You\u2019ll think you\u2019re writing imperative code!","date":"2019-06-07T00:00:00.000Z","tags":[],"readingTime":0.205,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"ArrowFx: Functional Programming for the masses","image":"https://img.youtube.com/vi/uyqqoooKpmI/maxresdefault.jpg","category":"videos","tag":["fx","videos"],"link":"https://www.youtube.com/watch?v=uyqqoooKpmI","event":"Kotliners, Budapest"},"unlisted":false,"prevItem":{"title":"Modular functional programming with Kotlin","permalink":"/community/blog/2019/07/02/modular-app-kotlin"},"nextItem":{"title":"How KEEP-87 & Typeclasses will change the way we write Kotlin","permalink":"/community/blog/2019/06/04/keep-87-and-typeclasses"}},"content":"In this talk we recap about the imminent future of Functional Programming in Kotlin. With ArrowFx you are able to encode \u201ceffectful\u201d programs in a controlled way following the FP principles through a direct syntax. You\u2019ll think you\u2019re writing imperative code!"},{"id":"/2019/06/04/keep-87-and-typeclasses","metadata":{"permalink":"/community/blog/2019/06/04/keep-87-and-typeclasses","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-06-04-keep-87-and-typeclasses.md","source":"@site/content/blog/2019-06-04-keep-87-and-typeclasses.md","title":"How KEEP-87 & Typeclasses will change the way we write Kotlin","description":"Short introduction into the proposal KEEP-87 and how it would be able to improve the language.","date":"2019-06-04T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.08,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"How KEEP-87 & Typeclasses will change the way we write Kotlin","image":"https://quickbirdstudios.com/blog/wp-content/uploads/2019/05/xFirebird.jpg.pagespeed.ic.e0DeqxTqSE.webp","category":"articles","tags":["core","articles"],"link":"https://quickbirdstudios.com/blog/keep-87-typeclasses-kotlin/"},"unlisted":false,"prevItem":{"title":"ArrowFx: Functional Programming for the masses","permalink":"/community/blog/2019/06/07/kotliners-arrow-fx"},"nextItem":{"title":"Introducing Arrow Playground","permalink":"/community/blog/2019/04/11/introducing-arrow-playground"}},"content":"Short introduction into the proposal [KEEP-87](https://github.com/Kotlin/KEEP/pull/87) and how it would be able to improve the language."},{"id":"/2019/04/11/introducing-arrow-playground","metadata":{"permalink":"/community/blog/2019/04/11/introducing-arrow-playground","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-04-11-introducing-arrow-playground.md","source":"@site/content/blog/2019-04-11-introducing-arrow-playground.md","title":"Introducing Arrow Playground","description":"Arrow Playground is a JavaScript library that creates Kotlin-aware, including Arrow, editors capable of running code from HTML block elements. This is a fork of the original Kotlin Playground work done by the JetBrains team.","date":"2019-04-11T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Introducing Arrow Playground","image":"https://www.47deg.com/assets/img/blog/featured_images/2019-04-11-introducing-arrow-playground.png","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/arrow-playground/"},"unlisted":false,"prevItem":{"title":"How KEEP-87 & Typeclasses will change the way we write Kotlin","permalink":"/community/blog/2019/06/04/keep-87-and-typeclasses"},"nextItem":{"title":"Immutable Conversations - Past and Future of Arrow","permalink":"/community/blog/2019/03/12/immutable-conv-1"}},"content":"Arrow Playground is a JavaScript library that creates Kotlin-aware, including Arrow, editors capable of running code from HTML block elements. This is a fork of the original Kotlin Playground work done by the JetBrains team."},{"id":"/2019/03/12/immutable-conv-1","metadata":{"permalink":"/community/blog/2019/03/12/immutable-conv-1","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-03-12-immutable-conv-1.md","source":"@site/content/blog/2019-03-12-immutable-conv-1.md","title":"Immutable Conversations - Past and Future of Arrow","description":"In this episode, we capture a conversation between Arrow maintainers Ra\xfal Raja and Paco Estevez as they discuss the past and future of the library which is designed to bring Functional Programming to Kotlin.","date":"2019-03-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.17,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Immutable Conversations - Past and Future of Arrow","image":"https://img.youtube.com/vi/YtchNDjQuTU/maxresdefault.jpg","category":"videos","tags":["core","fx","videos"],"link":"https://www.youtube.com/watch?v=YtchNDjQuTU"},"unlisted":false,"prevItem":{"title":"Introducing Arrow Playground","permalink":"/community/blog/2019/04/11/introducing-arrow-playground"},"nextItem":{"title":"From Imperative to Functional Programming using Arrow","permalink":"/community/blog/2019/02/10/imperative-functional-programming-arrow"}},"content":"In this episode, we capture a conversation between Arrow maintainers Ra\xfal Raja and Paco Estevez as they discuss the past and future of the library which is designed to bring Functional Programming to Kotlin."},{"id":"/2019/02/10/imperative-functional-programming-arrow","metadata":{"permalink":"/community/blog/2019/02/10/imperative-functional-programming-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-02-10-imperative-functional-programming-arrow.md","source":"@site/content/blog/2019-02-10-imperative-functional-programming-arrow.md","title":"From Imperative to Functional Programming using Arrow","description":"As its name implies, From Imperative to Functional Programming using Arrow is a tale about migrating a simple Kotlin application written in imperative style to a fully function application with the help of the Arrow library.","date":"2019-02-10T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"tutorials","permalink":"/community/blog/tags/tutorials"}],"readingTime":0.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"From Imperative to Functional Programming using Arrow","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"tutorials","tags":["core","fx","tutorials"],"link":"https://blog.frankel.ch/imperative-functional-programming/1/"},"unlisted":false,"prevItem":{"title":"Immutable Conversations - Past and Future of Arrow","permalink":"/community/blog/2019/03/12/immutable-conv-1"},"nextItem":{"title":"Webflux with Kotlin and Arrow","permalink":"/community/blog/2019/02/03/arrow-webflux"}},"content":"As its name implies, [From Imperative to Functional Programming using Arrow](https://blog.frankel.ch/imperative-functional-programming/1/) is a tale about migrating a simple Kotlin application written in imperative style to a fully function application with the help of the Arrow library."},{"id":"/2019/02/03/arrow-webflux","metadata":{"permalink":"/community/blog/2019/02/03/arrow-webflux","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-02-03-arrow-webflux.md","source":"@site/content/blog/2019-02-03-arrow-webflux.md","title":"Webflux with Kotlin and Arrow","description":"Webflux with Kotlin and Arrow shows how you can use Arrow together with Spring Webflux to create a reactive REST application. This article explains how to use the MonoK and the FluxK Arrow extensions together with the binding function to make working with the Mono and Flux reactor constructs much easier and better understandable.","date":"2019-02-03T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.27,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Webflux with Kotlin and Arrow","image":"/img/blog-image-header.png","category":"articles","tags":["core","fx","articles"],"link":"http://www.smartjava.org/content/webflux-arrow/"},"unlisted":false,"prevItem":{"title":"From Imperative to Functional Programming using Arrow","permalink":"/community/blog/2019/02/10/imperative-functional-programming-arrow"},"nextItem":{"title":"Getting started with FP in Kotlin and Arrow: Typeclasses","permalink":"/community/blog/2019/01/03/getting-started"}},"content":"[Webflux with Kotlin and Arrow](http://www.smartjava.org/content/webflux-arrow/) shows how you can use Arrow together with Spring Webflux to create a reactive REST application. This article explains how to use the `MonoK` and the `FluxK` Arrow extensions together with the `binding` function to make working with the `Mono` and `Flux` reactor constructs much easier and better understandable."},{"id":"/2019/01/03/getting-started","metadata":{"permalink":"/community/blog/2019/01/03/getting-started","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-01-03-getting-started.md","source":"@site/content/blog/2019-01-03-getting-started.md","title":"Getting started with FP in Kotlin and Arrow: Typeclasses","description":"Getting started with FP in Kotlin and Arrow: Typeclasses explores part of the Arrow library by explaining how you can use Arrow to create your own typeclasses and use the ones provided by Arrow to make your code more concise and better readable.","date":"2019-01-03T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.215,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Getting started with FP in Kotlin and Arrow: Typeclasses","image":"/img/blog-image-header.png","category":"articles","tags":["core","fx","articles"],"link":"http://www.smartjava.org/content/kotlin-arrow-typeclasses/"},"unlisted":false,"prevItem":{"title":"Webflux with Kotlin and Arrow","permalink":"/community/blog/2019/02/03/arrow-webflux"},"nextItem":{"title":"Functional Hangman Game written with Arrow","permalink":"/community/blog/2018/11/30/hangman"}},"content":"[Getting started with FP in Kotlin and Arrow: Typeclasses](http://www.smartjava.org/content/kotlin-arrow-typeclasses/) explores part of the Arrow library by explaining how you can use Arrow to create your own typeclasses and use the ones provided by Arrow to make your code more concise and better readable."},{"id":"/2018/11/30/hangman","metadata":{"permalink":"/community/blog/2018/11/30/hangman","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-11-30-hangman.md","source":"@site/content/blog/2018-11-30-hangman.md","title":"Functional Hangman Game written with Arrow","description":"Functional Hangman game - console application written with Arrow. Uses the IO monad to push side effects to the edge of the system.","date":"2018-11-30T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.115,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Hangman Game written with Arrow","image":"/img/blog-image-header.png","category":"articles","tags":["core","fx","articles"],"link":"https://lordraydenmk.github.io/2018/functional-hangman-in-kotlin-with-arrow/"},"unlisted":false,"prevItem":{"title":"Getting started with FP in Kotlin and Arrow: Typeclasses","permalink":"/community/blog/2019/01/03/getting-started"},"nextItem":{"title":"Manual documentation is dead. Long live automated documentation! Automated documentation with ANK","permalink":"/community/blog/2018/11/24/ank"}},"content":"[Functional Hangman](https://lordraydenmk.github.io/2018/functional-hangman-in-kotlin-with-arrow/) game - console application written with Arrow. Uses the `IO` monad to push side effects to the edge of the system."},{"id":"/2018/11/24/ank","metadata":{"permalink":"/community/blog/2018/11/24/ank","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-11-24-ank.md","source":"@site/content/blog/2018-11-24-ank.md","title":"Manual documentation is dead. Long live automated documentation! Automated documentation with ANK","description":"It includes how the ANK plugin works: from having a tool that evaluates and verifies your doc snippets at compile time, to generating code documentation that is always correct and up to date.","date":"2018-11-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"incubator","permalink":"/community/blog/tags/incubator"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.165,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Manual documentation is dead. Long live automated documentation! Automated documentation with ANK","image":"https://img.youtube.com/vi/kr8iWE4Jfhc/maxresdefault.jpg","category":"videos","tags":["core","incubator","videos"],"link":"https://www.youtube.com/watch?v=kr8iWE4Jfhc","event":"droidconSF, San Francisco"},"unlisted":false,"prevItem":{"title":"Functional Hangman Game written with Arrow","permalink":"/community/blog/2018/11/30/hangman"},"nextItem":{"title":"Simple Dependency Management in Kotlin","permalink":"/community/blog/2018/11/07/simple-management-dependency"}},"content":"It includes how the ANK plugin works: from having a tool that evaluates and verifies your doc snippets at compile time, to generating code documentation that is always correct and up to date."},{"id":"/2018/11/07/simple-management-dependency","metadata":{"permalink":"/community/blog/2018/11/07/simple-management-dependency","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-11-07-simple-management-dependency.md","source":"@site/content/blog/2018-11-07-simple-management-dependency.md","title":"Simple Dependency Management in Kotlin","description":"In this talk we introduce the concepts of Dependency Management as a language feature, typeclasses, and a live demo of KEEP-87. You can follow along the example in this folder.","date":"2018-11-07T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.15,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Simple Dependency Management in Kotlin","image":"https://img.youtube.com/vi/CR5h2Wq1yPE/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=CR5h2Wq1yPE","event":"AndroidTO, Toronto"},"unlisted":false,"prevItem":{"title":"Manual documentation is dead. Long live automated documentation! Automated documentation with ANK","permalink":"/community/blog/2018/11/24/ank"},"nextItem":{"title":"Polyjokes\u200a - \u200aA polymorphic approach using Arrow","permalink":"/community/blog/2018/10/21/polyjokes"}},"content":"In this talk we introduce the concepts of Dependency Management as a language feature, typeclasses, and a live demo of [KEEP-87](https://github.com/Kotlin/KEEP/pull/87). You can follow along the example in [this folder](https://github.com/arrow-kt/arrow/tree/master/modules/docs/arrow-examples/src/test/kotlin/arrow/typeclasses)."},{"id":"/2018/10/21/polyjokes","metadata":{"permalink":"/community/blog/2018/10/21/polyjokes","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-10-21-polyjokes.md","source":"@site/content/blog/2018-10-21-polyjokes.md","title":"Polyjokes\u200a - \u200aA polymorphic approach using Arrow","description":"@dcampogiani is using a polymorphic approach to retrieve a random user and then a joke about him.","date":"2018-10-21T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Polyjokes\u200a - \u200aA polymorphic approach using Arrow","image":"/img/blog-image-header.png","category":"articles","tags":["core","articles"],"link":"https://github.com/dcampogiani/polyjokes"},"unlisted":false,"prevItem":{"title":"Simple Dependency Management in Kotlin","permalink":"/community/blog/2018/11/07/simple-management-dependency"},"nextItem":{"title":"Architecting Typed FP Applications & Libraries in Kotlin with Arrow","permalink":"/community/blog/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow"}},"content":"[@dcampogiani](https://github.com/dcampogiani) is using a polymorphic approach to retrieve a random user and then a joke about him.\\n\\n[Polyjokes\u200a\u2014\u200aA polymorphic approach using Arrow](https://github.com/dcampogiani/polyjokes)"},{"id":"/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow","metadata":{"permalink":"/community/blog/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-10-05-kotlin-conf-fp-in-kotlin-with-arrow.md","source":"@site/content/blog/2018-10-05-kotlin-conf-fp-in-kotlin-with-arrow.md","title":"Architecting Typed FP Applications & Libraries in Kotlin with Arrow","description":"This talk includes a comprehensive walkthrough of the most important patterns covered by the data types and type classes we find in Arrow. Each pattern will be accompanied by code examples that illustrate how Arrow brings Typed Functional Programming to Kotlin.","date":"2018-10-05T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.22,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Architecting Typed FP Applications & Libraries in Kotlin with Arrow","image":"https://img.youtube.com/vi/VOZZTSuDMFE/maxresdefault.jpg","category":"videos","tags":["core","fx","videos"],"link":"https://www.youtube.com/watch?v=VOZZTSuDMFE","event":"KotlinConf, Amsterdam"},"unlisted":false,"prevItem":{"title":"Polyjokes\u200a - \u200aA polymorphic approach using Arrow","permalink":"/community/blog/2018/10/21/polyjokes"},"nextItem":{"title":"Arrow and Functional Programming for Kotlin Developers","permalink":"/community/blog/2018/07/24/arrow-fp-kotlin"}},"content":"This talk includes a comprehensive walkthrough of the most important patterns covered by the data types and type classes we find in Arrow. Each pattern will be accompanied by code examples that illustrate how Arrow brings Typed Functional Programming to Kotlin.\\n\\n[Sources and slides](https://github.com/47deg/arrow-architecture)"},{"id":"/2018/07/24/arrow-fp-kotlin","metadata":{"permalink":"/community/blog/2018/07/24/arrow-fp-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-07-24-arrow-fp-kotlin.md","source":"@site/content/blog/2018-07-24-arrow-fp-kotlin.md","title":"Arrow and Functional Programming for Kotlin Developers","description":"A beginner level introduction to Functional Programming for Kotlin and/or Android Developers or developers with OOP background.","date":"2018-07-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.085,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow and Functional Programming for Kotlin Developers","image":"https://img.youtube.com/vi/qYgilPqMOp0/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=qYgilPqMOp0","event":"DroidJam India, Bangalore, India"},"unlisted":false,"prevItem":{"title":"Architecting Typed FP Applications & Libraries in Kotlin with Arrow","permalink":"/community/blog/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow"},"nextItem":{"title":"Functional Programming in Kotlin with Arrow by Emmanuel Nhan","permalink":"/community/blog/2018/06/27/fp-kotlin-arrow"}},"content":"A beginner level introduction to Functional Programming for Kotlin and/or Android Developers or developers with OOP background."},{"id":"/2018/06/27/fp-kotlin-arrow","metadata":{"permalink":"/community/blog/2018/06/27/fp-kotlin-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-06-27-fp-kotlin-arrow.md","source":"@site/content/blog/2018-06-27-fp-kotlin-arrow.md","title":"Functional Programming in Kotlin with Arrow by Emmanuel Nhan","description":"@nhanmanu introduces Kotlin and how it is a good fit for functional programming. The talk goes through some interesting features of Kotlin, then show how to use them to enter the world of Higher Kinds and Typeclasses. In the last part, we explore some Arrow capabilities & built-in syntax, using validation as an example.","date":"2018-06-27T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks"}],"readingTime":0.27,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Programming in Kotlin with Arrow by Emmanuel Nhan","image":"https://image.slidesharecdn.com/fpkotlinsunnytech-180628144002/95/functional-programming-in-kotlin-with-arrow-sunnytech-2018-1-638.jpg","category":"slidedecks","tags":["core","slidedecks"],"link":"https://www.slideshare.net/EmmanuelNhan/functional-programming-in-kotlin-with-arrow-sunnytech-2018","event":"Sunny Tech, Montpellier"},"unlisted":false,"prevItem":{"title":"Arrow and Functional Programming for Kotlin Developers","permalink":"/community/blog/2018/07/24/arrow-fp-kotlin"},"nextItem":{"title":"Arrow 101\u200a - \u200aBuilding an Android app using Functional Programming","permalink":"/community/blog/2018/06/24/arrow-101"}},"content":"[@nhanmanu](https://twitter.com/nhanmanu) introduces Kotlin and how it is a good fit for functional programming. The talk goes through some interesting features of Kotlin, then show how to use them to enter the world of Higher Kinds and Typeclasses. In the last part, we explore some Arrow capabilities & built-in syntax, using validation as an example."},{"id":"/2018/06/24/arrow-101","metadata":{"permalink":"/community/blog/2018/06/24/arrow-101","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-06-24-arrow-101.md","source":"@site/content/blog/2018-06-24-arrow-101.md","title":"Arrow 101\u200a - \u200aBuilding an Android app using Functional Programming","description":"Leandro Ferreira presents how to build a simple app using Arrow and how to implement solutions with Semigroups.","date":"2018-06-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.17,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 101\u200a - \u200aBuilding an Android app using Functional Programming","image":"https://cdn-images-1.medium.com/max/2000/1*7HJJpOQE8M1-xXW0_5eePQ.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/@lehen01/arrow-101-building-an-android-app-using-functional-programming-fe959675d96d"},"unlisted":false,"prevItem":{"title":"Functional Programming in Kotlin with Arrow by Emmanuel Nhan","permalink":"/community/blog/2018/06/27/fp-kotlin-arrow"},"nextItem":{"title":"State of the functional ecosystem in Kotlin: Mid 2018 checkup","permalink":"/community/blog/2018/06/24/state-ecosystem"}},"content":"[Leandro Ferreira](https://twitter.com/mLeandroBF) presents how to build a simple app using Arrow and how to implement solutions with Semigroups.\\n\\n[Arrow 101\u200a\u2014\u200aBuilding an Android app using Functional Programming](https://medium.com/@lehen01/arrow-101-building-an-android-app-using-functional-programming-fe959675d96d)\\n\\n[Arrow 101\u200a\u2014\u200aModelling a real world problem with Semigroups](https://medium.com/@lehen01/arrow-101-modelling-a-real-world-problem-with-semigroups-d8f22cdf54c)"},{"id":"/2018/06/24/state-ecosystem","metadata":{"permalink":"/community/blog/2018/06/24/state-ecosystem","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-06-24-state-ecosystem.md","source":"@site/content/blog/2018-06-24-state-ecosystem.md","title":"State of the functional ecosystem in Kotlin: Mid 2018 checkup","description":"This talk focuses on the day-to-day problems Arrow solves, from small ideas to big concepts.","date":"2018-06-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"incubator","permalink":"/community/blog/tags/incubator"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"State of the functional ecosystem in Kotlin: Mid 2018 checkup","image":"https://img.youtube.com/vi/q_1xPYQLyaU/maxresdefault.jpg","category":"videos","tags":["core","optics","fx","incubator","videos"],"link":"https://www.youtube.com/watch?v=q_1xPYQLyaU","event":"Conference for Kotliners, Budapest"},"unlisted":false,"prevItem":{"title":"Arrow 101\u200a - \u200aBuilding an Android app using Functional Programming","permalink":"/community/blog/2018/06/24/arrow-101"},"nextItem":{"title":"Higher Kinded Types in a Lower Kinded Language by Jacob Bass","permalink":"/community/blog/2018/06/22/hk-types"}},"content":"This talk focuses on the day-to-day problems Arrow solves, from small ideas to big concepts.\\n\\nIt includes an overview of all the modules available, and some of the 3rd party libraries made by the community."},{"id":"/2018/06/22/hk-types","metadata":{"permalink":"/community/blog/2018/06/22/hk-types","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-06-22-hk-types.md","source":"@site/content/blog/2018-06-22-hk-types.md","title":"Higher Kinded Types in a Lower Kinded Language by Jacob Bass","description":"It\'s hard coming back down to the earth of a JVM based language after spending time with Haskell and OCaml. This talk will discuss functional programming in Kotlin with the Arrow library, how the abstractions it provides can improve your code, and how this magic that provides higher-kinded types works under the hood.","date":"2018-06-22T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.265,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Higher Kinded Types in a Lower Kinded Language by Jacob Bass","image":"https://img.youtube.com/vi/ERM0mBPNLHc/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=ERM0mBPNLHc","event":"Yow! Lambda Jam, Sydney, Australia"},"unlisted":false,"prevItem":{"title":"State of the functional ecosystem in Kotlin: Mid 2018 checkup","permalink":"/community/blog/2018/06/24/state-ecosystem"},"nextItem":{"title":"1/n - How do I\u2026 in FP: Validation","permalink":"/community/blog/2018/04/23/how-do-i"}},"content":"It\'s hard coming back down to the earth of a JVM based language after spending time with Haskell and OCaml. This talk will discuss functional programming in Kotlin with the Arrow library, how the abstractions it provides can improve your code, and how this magic that provides higher-kinded types works under the hood."},{"id":"/2018/04/23/how-do-i","metadata":{"permalink":"/community/blog/2018/04/23/how-do-i","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-04-23-how-do-i.md","source":"@site/content/blog/2018-04-23-how-do-i.md","title":"1/n - How do I\u2026 in FP: Validation","description":"Emmanuel Nhan showcases different approaches to validation including examples for ValidatedNel from Arrow in this great and in depth post using Kafka Streams Config parameters as example.","date":"2018-04-23T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"tutorials","permalink":"/community/blog/tags/tutorials"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"1/n - How do I\u2026 in FP: Validation","image":"https://images.unsplash.com/photo-1518169811655-27c3a4327016?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=600&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=383b467064497d356a0b05b3a3d180be","category":"tutorials","tags":["core","tutorials"],"link":"https://www.enhan.eu/how-to-in-fp/"},"unlisted":false,"prevItem":{"title":"Higher Kinded Types in a Lower Kinded Language by Jacob Bass","permalink":"/community/blog/2018/06/22/hk-types"},"nextItem":{"title":"Android Functional Validation","permalink":"/community/blog/2018/04/14/android-functional-validation"}},"content":"[Emmanuel Nhan](https://www.enhan.eu/author/enhan/) showcases different approaches to validation including examples for `ValidatedNel` from Arrow in this great and in depth post using Kafka Streams Config parameters as example.\\n\\n[1/n - How do I\u2026 in FP: Validation](https://www.enhan.eu/how-to-in-fp/)"},{"id":"/2018/04/14/android-functional-validation","metadata":{"permalink":"/community/blog/2018/04/14/android-functional-validation","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-04-14-android-functional-validation.md","source":"@site/content/blog/2018-04-14-android-functional-validation.md","title":"Android Functional Validation","description":"@dcampogiani explores some data types in Arrow and uses them to validate a form on Android.","date":"2018-04-14T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"tutorials","permalink":"/community/blog/tags/tutorials"}],"readingTime":0.135,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Android Functional Validation","image":"https://i.vimeocdn.com/video/713283357_1280x720.jpg","category":"tutorials","tags":["core","tutorials"],"link":"https://player.vimeo.com/video/279931528"},"unlisted":false,"prevItem":{"title":"1/n - How do I\u2026 in FP: Validation","permalink":"/community/blog/2018/04/23/how-do-i"},"nextItem":{"title":"Introduction to Kotlin Arrow by Jacob Bass","permalink":"/community/blog/2018/03/26/kotlin-arrow"}},"content":"[@dcampogiani](https://github.com/dcampogiani) explores some data types in Arrow and uses them to validate a form on Android.\\n\\n[Video (in italian)](https://player.vimeo.com/video/279931528)\\n\\n* [Introduction](http://danielecampogiani.com/blog/2018/02/android-functional-validation-1-intro/)\\n* [Option](http://danielecampogiani.com/blog/2018/02/android-functional-validation-2-option/)\\n* [Either](http://danielecampogiani.com/blog/2018/02/android-functional-validation-3-either/)\\n* [Validated](http://danielecampogiani.com/blog/2018/02/android-functional-validation-4-validated/)"},{"id":"/2018/03/26/kotlin-arrow","metadata":{"permalink":"/community/blog/2018/03/26/kotlin-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-03-26-kotlin-arrow.md","source":"@site/content/blog/2018-03-26-kotlin-arrow.md","title":"Introduction to Kotlin Arrow by Jacob Bass","description":"@bassjacob goes through how Funktionale and Kategory merged into Arrow, consolidating two of the most popular FP libraries in the Kotlin space into one powerhouse. The talk is an introduction to some FP concepts, how the libraries work, what features they bring to the table and where you might use them in your code.","date":"2018-03-26T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.27,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Introduction to Kotlin Arrow by Jacob Bass","image":"https://img.youtube.com/vi/tM2wEI-e80E/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=tM2wEI-e80E","event":"Kotlin Meetup, Sydney"},"unlisted":false,"prevItem":{"title":"Android Functional Validation","permalink":"/community/blog/2018/04/14/android-functional-validation"},"nextItem":{"title":"It\'s all about morphisms","permalink":"/community/blog/2018/03/21/morphisms"}},"content":"[@bassjacob](https://github.com/bassjacob) goes through how Funktionale and Kategory merged into Arrow, consolidating two of the most popular FP libraries in the Kotlin space into one powerhouse. The talk is an introduction to some FP concepts, how the libraries work, what features they bring to the table and where you might use them in your code."},{"id":"/2018/03/21/morphisms","metadata":{"permalink":"/community/blog/2018/03/21/morphisms","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-03-21-morphisms.md","source":"@site/content/blog/2018-03-21-morphisms.md","title":"It\'s all about morphisms","description":"@uberto gives a gentle introduction to Category Theory for programmers used to OOP but interested in Functional Programming. No Haskell knowledge required. We will explain main concepts behind functional programming with many diagrams and simple metaphors and examples. Some code will clarify how to translate these ideas in programs.","date":"2018-03-21T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.245,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"It\'s all about morphisms","image":"https://img.youtube.com/vi/Eq8dv4H3RTE/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=Eq8dv4H3RTE","event":"Voxxed Days, Vienna"},"unlisted":false,"prevItem":{"title":"Introduction to Kotlin Arrow by Jacob Bass","permalink":"/community/blog/2018/03/26/kotlin-arrow"},"nextItem":{"title":"Optics and Type Classes in Arrow","permalink":"/community/blog/2018/01/17/optics-type-classes-arrow"}},"content":"[@uberto](https://github.com/uberto) gives a gentle introduction to Category Theory for programmers used to OOP but interested in Functional Programming. No Haskell knowledge required. We will explain main concepts behind functional programming with many diagrams and simple metaphors and examples. Some code will clarify how to translate these ideas in programs."},{"id":"/2018/01/17/optics-type-classes-arrow","metadata":{"permalink":"/community/blog/2018/01/17/optics-type-classes-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-01-17-optics-type-classes-arrow.md","source":"@site/content/blog/2018-01-17-optics-type-classes-arrow.md","title":"Optics and Type Classes in Arrow","description":"@msya explains how to use various optics and type classes in Arrow. He discusses optics such as","date":"2018-01-17T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks"}],"readingTime":0.215,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Optics and Type Classes in Arrow","image":"https://speakerd.s3.amazonaws.com/presentations/4b938d99415a416c8f908ac5302a66cb/slide_0.jpg","category":"slidedecks","tags":["core","optics","slidedecks"],"event":"Kotlin Brooklyn Meetup","link":"https://speakerdeck.com/heyitsmohit/functional-programming-with-arrow"},"unlisted":false,"prevItem":{"title":"It\'s all about morphisms","permalink":"/community/blog/2018/03/21/morphisms"},"nextItem":{"title":"Functional Programming in Kotlin with Arrow","permalink":"/community/blog/2017/11/29/fp-kotlin-arrow"}},"content":"[@msya](https://github.com/msya) explains how to use various optics and type classes in Arrow. He discusses optics such as\\n[`Lens`](https://arrow-kt.io/learn/immutable-data/lens/) and [`Iso`](https://arrow-kt.io/learn/immutable-data/prism-iso/). He also goes over the purpose for type classes and how [KEEP-87](https://github.com/Kotlin/KEEP/pull/87) will make it easier to implement them.\\n\\n[Functional Programming with Arrow](https://speakerdeck.com/heyitsmohit/functional-programming-with-arrow)"},{"id":"/2017/11/29/fp-kotlin-arrow","metadata":{"permalink":"/community/blog/2017/11/29/fp-kotlin-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-29-fp-kotlin-arrow.md","source":"@site/content/blog/2017-11-29-fp-kotlin-arrow.md","title":"Functional Programming in Kotlin with Arrow","description":"A rundown of all the features included in the library, focusing on implementation details.","date":"2017-11-29T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Programming in Kotlin with Arrow","image":"https://img.youtube.com/vi/IL5XzaCMKpQ/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=IL5XzaCMKpQ","event":"Lambda World, C\xe1diz"},"unlisted":false,"prevItem":{"title":"Optics and Type Classes in Arrow","permalink":"/community/blog/2018/01/17/optics-type-classes-arrow"},"nextItem":{"title":"Building a DSL\u2026 in Kotlin","permalink":"/community/blog/2017/11/24/building-dsl-kotlin"}},"content":"A rundown of all the features included in the library, focusing on implementation details."},{"id":"/2017/11/24/building-dsl-kotlin","metadata":{"permalink":"/community/blog/2017/11/24/building-dsl-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-24-building-dsl-kotlin.md","source":"@site/content/blog/2017-11-24-building-dsl-kotlin.md","title":"Building a DSL\u2026 in Kotlin","description":"Make DSLs stack safe, composable and reusable under different runtime requirements thanks to Arrow.","date":"2017-11-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Building a DSL\u2026 in Kotlin","image":"https://img.youtube.com/vi/qGef3sFAIxU/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=qGef3sFAIxU","event":"droidconSF, San Francisco"},"unlisted":false,"prevItem":{"title":"Functional Programming in Kotlin with Arrow","permalink":"/community/blog/2017/11/29/fp-kotlin-arrow"},"nextItem":{"title":"Happy path: Kotlin + Actors + Arrow","permalink":"/community/blog/2017/11/22/happy-path"}},"content":"Make DSLs stack safe, composable and reusable under different runtime requirements thanks to Arrow."},{"id":"/2017/11/22/happy-path","metadata":{"permalink":"/community/blog/2017/11/22/happy-path","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-22-happy-path.md","source":"@site/content/blog/2017-11-22-happy-path.md","title":"Happy path: Kotlin + Actors + Arrow","description":"@javipacheco creates a Proof of Concept architecture for Android using the Actor pattern and modelling the domain with Either.","date":"2017-11-22T00:00:00.000Z","tags":[],"readingTime":0.13,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Happy path: Kotlin + Actors + Arrow","image":"https://cdn-images-1.medium.com/max/600/1*kF_bpeNe0THMssFEa2enYA.jpeg","category":"articles","tag":["core","articles"],"link":"https://medium.com/@javipacheco/happy-path-kotlin-actors-arrow-proof-of-concept-322e9099d2ea"},"unlisted":false,"prevItem":{"title":"Building a DSL\u2026 in Kotlin","permalink":"/community/blog/2017/11/24/building-dsl-kotlin"},"nextItem":{"title":"Architectures Using Functional Programming Concepts","permalink":"/community/blog/2017/11/17/architectures"}},"content":"[@javipacheco](https://github.com/javipacheco) creates a Proof of Concept architecture for Android using the Actor pattern and modelling the domain with [`Either`](https://apidocs.arrow-kt.io/arrow-core/arrow.core/-either/index.html).\\n\\n[Happy Path: Kotlin + Actors + Arrow](https://medium.com/@javipacheco/happy-path-kotlin-actors-arrow-proof-of-concept-322e9099d2ea)"},{"id":"/2017/11/17/architectures","metadata":{"permalink":"/community/blog/2017/11/17/architectures","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-17-architectures.md","source":"@site/content/blog/2017-11-17-architectures.md","title":"Architectures Using Functional Programming Concepts","description":"Introductory talk to Functional architectures to be built on top of Arrow.","date":"2017-11-17T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Architectures Using Functional Programming Concepts","image":"https://img.youtube.com/vi/qI1ctQ0293o/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=qI1ctQ0293o","event":"KotlinConf, San Francisco"},"unlisted":false,"prevItem":{"title":"Happy path: Kotlin + Actors + Arrow","permalink":"/community/blog/2017/11/22/happy-path"},"nextItem":{"title":"Kotlin for the Pragmatic Functionalist","permalink":"/community/blog/2017/11/09/pragmatic-functionalist"}},"content":"Introductory talk to Functional architectures to be built on top of Arrow."},{"id":"/2017/11/09/pragmatic-functionalist","metadata":{"permalink":"/community/blog/2017/11/09/pragmatic-functionalist","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-09-pragmatic-functionalist.md","source":"@site/content/blog/2017-11-09-pragmatic-functionalist.md","title":"Kotlin for the Pragmatic Functionalist","description":"An introduction to Arrow and the enhancements it brings to Kotlin\'s standard library.","date":"2017-11-09T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.065,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin for the Pragmatic Functionalist","image":"https://img.youtube.com/vi/s9oMED6ZikQ/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=s9oMED6ZikQ","event":"KotlinConf, San Francisco"},"unlisted":false,"prevItem":{"title":"Architectures Using Functional Programming Concepts","permalink":"/community/blog/2017/11/17/architectures"},"nextItem":{"title":"Functional Programming in Kotlin","permalink":"/community/blog/2017/11/02/fp-kotlin"}},"content":"An introduction to Arrow and the enhancements it brings to Kotlin\'s standard library."},{"id":"/2017/11/02/fp-kotlin","metadata":{"permalink":"/community/blog/2017/11/02/fp-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-02-fp-kotlin.md","source":"@site/content/blog/2017-11-02-fp-kotlin.md","title":"Functional Programming in Kotlin","description":"An ongoing blog series introducing Functional Programming architectures from scratch","date":"2017-11-02T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"mtl","permalink":"/community/blog/tags/mtl"},{"label":"tutorials","permalink":"/community/blog/tags/tutorials"}],"readingTime":0.145,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Programming in Kotlin","image":"https://cdn-images-1.medium.com/max/600/1*NpQ5mqoY4SH5iwsWG35RqQ.jpeg","category":"tutorials","tags":["core","fx","mtl","tutorials"],"link":"https://medium.com/@JorgeCastilloPr/kotlin-functional-programming-does-it-make-sense-36ad07e6bacf"},"unlisted":false,"prevItem":{"title":"Kotlin for the Pragmatic Functionalist","permalink":"/community/blog/2017/11/09/pragmatic-functionalist"},"nextItem":{"title":"Functional approach to Android architecture using Kotlin","permalink":"/community/blog/2017/10/20/functional-approach"}},"content":"An ongoing blog series introducing Functional Programming architectures from scratch\\n\\n[Kotlin Functional Programming: Does it make sense?](https://medium.com/@JorgeCastilloPr/kotlin-functional-programming-does-it-make-sense-36ad07e6bacf)\\n\\n[Kotlin Functional Programming I: Monad Stack](https://medium.com/@JorgeCastilloPr/kotlin-functional-programming-i-monad-stack-518d1bd8fbee)\\n\\n[Kotlin Functional Programming II: Monad Transformers](https://medium.com/@JorgeCastilloPr/kotlin-functional-programming-ii-monad-transformers-b1f020f14dd8)"},{"id":"/2017/10/20/functional-approach","metadata":{"permalink":"/community/blog/2017/10/20/functional-approach","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-10-20-functional-approach.md","source":"@site/content/blog/2017-10-20-functional-approach.md","title":"Functional approach to Android architecture using Kotlin","description":"Move side effects to the edges of the system, implement a functional oriented architecture for Android apps based on purity.","date":"2017-10-20T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.1,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional approach to Android architecture using Kotlin","image":"https://img.youtube.com/vi/qGef3sFAIxU/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=qGef3sFAIxU","event":"Mobilization 7, \u0141\xf3d\u017a"},"unlisted":false,"prevItem":{"title":"Functional Programming in Kotlin","permalink":"/community/blog/2017/11/02/fp-kotlin"},"nextItem":{"title":"Handling exceptions in Arrow","permalink":"/community/blog/2017/09/17/handling-exceptions-arrow"}},"content":"Move side effects to the edges of the system, implement a functional oriented architecture for Android apps based on purity."},{"id":"/2017/09/17/handling-exceptions-arrow","metadata":{"permalink":"/community/blog/2017/09/17/handling-exceptions-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-09-17-handling-exceptions-arrow.md","source":"@site/content/blog/2017-09-17-handling-exceptions-arrow.md","title":"Handling exceptions in Arrow","description":"@uris77 explains how to use Try in real world examples.","date":"2017-09-17T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.095,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Handling exceptions in Arrow","image":"/img/blog-image-header.png","category":"articles","tags":["core","articles"],"link":"https://www.spantree.net/blog/2017/09/15/kotlin-exception-handling-with-kategory.html"},"unlisted":false,"prevItem":{"title":"Functional approach to Android architecture using Kotlin","permalink":"/community/blog/2017/10/20/functional-approach"}},"content":"[@uris77](https://github.com/uris77) explains how to use [Try](https://arrow-kt.io/docs/apidocs/arrow-core-data/arrow.core/-try/) in real world examples.\\n\\n[Handling Kotlin Exceptions with Arrow \u2013 A Functional Approach](https://www.spantree.net/blog/2017/09/15/kotlin-exception-handling-with-kategory.html)"}]}}')}}]); \ No newline at end of file diff --git a/assets/js/e41df212.d3cb67b2.js b/assets/js/e41df212.d3cb67b2.js new file mode 100644 index 00000000..19ec64f6 --- /dev/null +++ b/assets/js/e41df212.d3cb67b2.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[2348],{22761:e=>{e.exports=JSON.parse('{"archive":{"blogPosts":[{"id":"/2024/10/03/arrow-open-space","metadata":{"permalink":"/community/blog/2024/10/03/arrow-open-space","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-10-03-arrow-open-space.md","source":"@site/content/blog/2024-10-03-arrow-open-space.md","title":"Arrow Open Space @ Lambda World","description":"The first Arrow & Fuctional Kotlin Open Space is taking place as part of Lambda World! This post contains the preliminary schedule, and shall be updated after the Open Space takes place with additional material, slides, and videos.","date":"2024-10-03T00:00:00.000Z","tags":[{"label":"articles","permalink":"/community/blog/tags/articles"},{"label":"community","permalink":"/community/blog/tags/community"}],"readingTime":1.875,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Open Space @ Lambda World","category":"articles","tags":["articles","community"],"image":"https://pub-c7459893ae854bbdb5ad00855f44c0c8.r2.dev/LandingPage_Lambda/Lambda_Logo_Blue.svg"},"unlisted":false,"nextItem":{"title":"Arrow plug-in for IntelliJ 0.1 is here!","permalink":"/community/blog/2024/06/01/intellij-plugin"}},"content":"The first [Arrow & Fuctional Kotlin Open Space](https://www.lambda.world/workshops/Arrow%20%26%20Functional%20Kotlin%20Open%20Space/) is taking place as part of [Lambda World](https://lambda.world)! This post contains the preliminary schedule, and shall be updated after the Open Space takes place with additional material, slides, and videos.\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n
14.30 - 15.00Introduction to Arrow libraries by Simon Vergauwen
15.00 - 16.30Unconference and Build together (in parallel, see below)
16.30 - 16.50Closing remarks
\\n\\n## Unconference\\n\\nWe have a nice room, some sweets, and a nice projector. The perfect setup to share some knowledge about Arrow and Functional Kotlin! Our goal with the Unconference is to bring together people who can talk about something and people who want to learn about something.\\n\\n_How does it work?_ Please talk to one of the people in charge so they can change the spreadsheet.\\n\\n- If you want to learn about a topic...\\n - If the topic is not yet in the spreadsheet, add it in the first column with the _Requested_ status.\\n - If the topic is in the spreadsheet, contact the potential speaker.\\n- If you want to talk about a topic...\\n - If it is already in the spreadsheet, shout it out loud and let the talk begin!\\n - If not, add your topic and name with the _Waiting_ status, and wait for somebody to request it.\\n- Once the talk begins, change it status to _In progress_, and once it is finished, move it to _Done_.\\n - It would be great if any material or code would be shared with the organizers, so we can later add it to this page.\\n\\n\\n\\n\\n## Build together\\n\\nThe goal of the Open Space is to learn. Many of us around are happy to help, so feel free to work in any project you want, and explore ways to use more functional features in your Kotlin. Once again, don\'t be shy to ask :)\\n\\nIf you are not sure about where to start, we have prepared a few tutorials and projects for you.\\n\\n- [Pok\xe9-Fun with Kotlin and Arrow](https://serranofp.com/poke-fun/): exercises about different parts of Arrow, and how you can apply them to a Compose Multiplatform project.\\n- [Example projects](https://arrow-kt.io/learn/design/projects/) from the Arrow documentation"},{"id":"/2024/06/01/intellij-plugin","metadata":{"permalink":"/community/blog/2024/06/01/intellij-plugin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-06-01-intellij-plugin.md","source":"@site/content/blog/2024-06-01-intellij-plugin.md","title":"Arrow plug-in for IntelliJ 0.1 is here!","description":"One of the main goals of the Arrow project is to produce libraries","date":"2024-06-01T00:00:00.000Z","tags":[{"label":"intellij","permalink":"/community/blog/tags/intellij"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":1.41,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow plug-in for IntelliJ 0.1 is here!","category":"articles","tags":["intellij","articles"]},"unlisted":false,"prevItem":{"title":"Arrow Open Space @ Lambda World","permalink":"/community/blog/2024/10/03/arrow-open-space"},"nextItem":{"title":"Arrow 1.2.3 release","permalink":"/community/blog/2024/02/28/arrow-1-2-3"}},"content":"One of the main goals of the Arrow project is to produce libraries\\nthat follow well-known Kotlin idioms, and we strive to make them\\nas discoverable as possible. Nevertheless, the surface of some\\ncomponents, like [typed errors](/learn/typed-errors/),\\nis quite large.\\nFor that reason, we have been busy in the last weeks preparing\\nthe first release of the\\n[Arrow plug-in for IntelliJ-based IDEs](https://plugins.jetbrains.com/plugin/24550-arrow).\\n\\nThis first version already focuses on three different aspects of\\nArrow usage where we found that an additional companion can make\\na big difference. The first aspect is the usage of typed errors:\\nthe IDE will now suggest missing `.bind()` or `.bindAll()`,\\nmapping of error using `withError`, and promoting idioms like\\n`ensure` whenever possible.\\n\\nThe second aspect is warning about wrong usages of Arrow APIs\\nwhich cannot be prevented by Kotlin\'s type system alone. This includes\\nescaping of `Raise` contexts -- for example, using `sequence` or\\n`flow` inside `either` --, using `Atomic` with primitive types \\n-- where `AtomicInt` or `AtomicBoolean` should be used instead --,\\nor matching on `Eval` instances directly instead of using the\\nprovided API -- which can easily lead to broken invariants.\\n\\nThe third aspect is applying some known recipes which may be hard\\nto know upfront. The first release includes a suggestion to add\\nthe corresponding [serializer](/learn/quickstart/serialization/)\\nwhen a type marked as `@Serializable` includes an Arrow Core type.\\nThis is an area which we would like to explore more, helping with\\nthe difficulties raised by the community.\\n\\nThe plug-in lives in a [separate repository](https://github.com/arrow-kt/arrow-intellij).\\nPlease let us know your experience, and don\'t be shy to open issues\\nwith suggestions for more features. They would help not only you\\nbut potentially every user of the Arrow library."},{"id":"/2024/02/28/arrow-1-2-3","metadata":{"permalink":"/community/blog/2024/02/28/arrow-1-2-3","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2024-02-28-arrow-1-2-3.md","source":"@site/content/blog/2024-02-28-arrow-1-2-3.md","title":"Arrow 1.2.3 release","description":"We are happy to announce the availability of version 1.2.3 of the Arrow collection of libraries.","date":"2024-02-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":4.65,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 1.2.3 release","category":"articles","tags":["core","articles"]},"unlisted":false,"prevItem":{"title":"Arrow plug-in for IntelliJ 0.1 is here!","permalink":"/community/blog/2024/06/01/intellij-plugin"},"nextItem":{"title":"Arrow releases stable 1.2.0 version","permalink":"/community/blog/2023/07/12/arrow-1-2-0"}},"content":"We are happy to announce the availability of version 1.2.3 of the Arrow collection of libraries.\\nAccording to our plan, this is the last non-bugfix release of the 1.x series.\\nFrom now on, our `main` branch targets Arrow 2.0, which should be the next major release.\\n\\nWe are incredibly thankful to the many people that have contributed to this release,\\nbringing new ideas and quite some code.\\n\\n:::info Please use 1.2.4\\n\\nVersion 1.2.3 of `arrow-core` changed the behavior of `Raise` computations returning\\nfunctions or sequences. This change [restricted some useful usages](https://github.com/arrow-kt/arrow/issues/3391),\\nso the team has decided to roll it back and keep the 1.2.1 behavior.\\n\\n:::\\n\\n## New features\\n\\nA version number like 1.2.3 sounds like a small bugfix release, but this is far from truth in\\nthis case: this release is full of new modules to help you be productive when writing Kotlin.\\n\\n### Improved focus on Compose\\n\\nArrow provides building blocks relevant to many projects using Kotlin.\\nA large part of our community is doing frontend work, and during the latest months,\\nthe team has been trying to understand their needs, in order to make Arrow\\na relevant tool in that space.\\n\\nFrom that journey, we have put together a new documentation page highlighting\\ndifferent ways in which Arrow may be useful in your Compose application.\\nThere is also a new [`arrow-optics-compose` module](/learn/immutable-data/lens/#integration-with-compose)\\nthat includes utilities to work with immutable data inside a `MutableState`\\nor `MutableStateFlow`.\\n\\nWe are eager to hear more use cases or needs where Arrow may help the lives\\nof Kotlin developers. Feel free to drop by the `#arrow` channel in the Kotlin Slack,\\nor open an issue or discussion in our [repository](https://github.com/arrow-kt/arrow).\\n\\n### Non-`suspend` resource management\\n\\n[Resource safety](/learn/coroutines/resource-safety/) in Arrow\\nhas been traditionally tied to the use of coroutines and `suspend` functions.\\nThis is the right choice for Kotlin-first libraries, like Ktor or Koin, but many\\nlibraries still come from a Java background where no such feature exists.\\nBeginning with this version, we provide two \\"variations\\" of resource management:\\n\\n- `Resource`, from the `arrow-fx-coroutines` module, is based on `suspend`\\n and ensures the desired behavior alongside coroutines (including cancellation).\\n- `AutoClose`, from the new `arrow-autoclose` module, provides almost the\\n same API as `Resource`, but without the `suspend` requirement.\\n\\n### Forward compatible `Eval`\\n\\nOne of our goals is to make the transition to 2.0 as smooth as possible.\\nYou can [already migrate](/learn/quickstart/migration/)\\nto the new APIs by using Arrow 1.2.3, and then ensuring that you get no deprecation warnings.\\n\\nDuring this process, we were [made aware](https://github.com/arrow-kt/arrow/issues/3039) that\\nthere was no clear story for the migration of `Eval`. On the other hand, the use cases are very narrow.\\nThe decision was to create a new [`arrow-eval` module](/learn/collections-functions/eval/),\\npresent since this release, and mark the one from `arrow-core` point the new module,\\ninstead of entirely removing this functionality from Arrow.\\n\\n### Collectors\\n\\nThe new [`arrow-collectors` module](/learn/collections-functions/collectors/)\\nallows composing operations over sequences of values\\n(lists, flows, sequences) while ensuring that the sequence is traversed only once.\\nThis property is especially relevant when building the sequence is expensive, or simply\\ncannot be reproduced, like a stream of data from a database or a flow of actions.\\n\\n## Improved features\\n\\nSeveral features in the library have been improved, to ensure that Arrow covers a variety\\nof use cases.\\n\\n### Lenses for sealed classes\\n\\nThis was once of the [older feature requests](https://github.com/arrow-kt/arrow/issues/2829)\\nstill in our issue tracker, which is now closed thanks to a wonderful\\n[contribution](https://github.com/arrow-kt/arrow/pull/3359)!\\n\\nFrom now on, the Optics KSP plug-in can generate\\n[lenses for sealed hierarchies](/learn/immutable-data/lens/#sealed-class-hierarchies),\\ngiven that the field lives in the common parent. For example, the following code\\n\\n```kotlin\\n@optics sealed interface User {\\n val name: String\\n\\n data class Person(override val name: String, val age: Int): User\\n data class Company(override val name: String, val vat: VATNumber): User\\n}\\n```\\n\\ngenerates from this version on both prisms for each choice, and a lens for `name`.\\n\\n### Higher-arity functions\\n\\nWe have traditionally been reluctant to add variations of `zip` with more than\\n10 parameters, because we felt that the narrow use cases did not balance out\\nthe increase in binary size. Since this release Arrow provides those functions\\nin a new `arrow-core-high-arity` module.\\n\\n### More accumulating functions for `Raise`\\n\\n[Typed errors](/learn/typed-errors/working-with-typed-errors/)\\nprovide two essential ways to [accumulate errors](/learn/typed-errors/working-with-typed-errors/#accumulating-errors): `zipOrAccumulate` and `mapOrAccumulate`. Those correspond\\nto accumulating over a fixed number of computations of different types, or\\naccumulating over an unknown quantity of computations with the same type.\\n\\nThe `mapOrAccumulate` function _always_ returns a new list. In some cases, you\\ndon\'t really care about this result, just about the iteration behavior.\\nThis is similar to the different between `map` and `forEach` in the standard\\nlibrary. From there Arrow takes the name of the new function: `forEachAccumulating`.\\n\\nOne potential use case is performing validation over elements of a list,\\nbut keeping the values intact.\\n\\n```kotlin\\npeople.forEachAccumulating { person ->\\n ensure(person.age >= 0) { InvalidAge(person.name) }\\n}\\n```\\n\\n### Better memoization\\n\\n[`MemoizedDeepRecursiveFunction`](/learn/collections-functions/recursive/#memoized-recursive-functions)\\nis a powerful tool to express recursive algorithms without worries over stack overflow or recomputation.\\nHowever, there was a lack of control over how memoized values were stored or evicted, which made the\\ntype less useful than intended.\\n\\nFrom this release on, there are new overloads to support custom memoization policies.\\nFurthermore, the new [`arrow-cache4k` module](/learn/collections-functions/recursive/#memoization-takes-memory)\\nprovides integration with the excellent\\n[cache4k](https://github.com/ReactiveCircus/cache4k) library.\\n\\n## More integrations\\n\\nAlthough not part of this release, we would like to highlight that\\n[Akkurate](https://akkurate.dev), which provides a wonderful DSL for validation over data,\\nhas released an [integration module for Arrow](https://akkurate.dev/docs/arrow-integration.html).\\nThis adds to the [rest of integrations](/learn/integrations/)\\nand shows the collaborative spirit of the Kotlin community."},{"id":"/2023/07/12/arrow-1-2-0","metadata":{"permalink":"/community/blog/2023/07/12/arrow-1-2-0","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-07-12-arrow-1-2-0.md","source":"@site/content/blog/2023-07-12-arrow-1-2-0.md","title":"Arrow releases stable 1.2.0 version","description":"We\'re excited to announce the stable Arrow 1.2.0 version. To briefly summarize, this release:","date":"2023-07-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.32,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow releases stable 1.2.0 version","image":"https://xebia.com/wp-content/uploads/2023/04/arrow-release-ftr.jpg","category":"articles","tags":["core","articles"],"link":"https://xebia.com/blog/a-new-module-for-typed-errors-in-arrow-1-2-0/"},"unlisted":false,"prevItem":{"title":"Arrow 1.2.3 release","permalink":"/community/blog/2024/02/28/arrow-1-2-3"},"nextItem":{"title":"Arrow 2.0\'s Trajectory - Video","permalink":"/community/blog/2023/05/04/arrow-trajectory-kotlinconf"}},"content":"We\'re excited to announce the stable Arrow 1.2.0 version. To briefly summarize, this release:\\n\\n- Improves the API for [typed errors](http://arrow-kt.io/learn/typed-errors/working-with-typed-errors/),\\n including [`withError`](https://apidocs.arrow-kt.io/arrow-core/arrow.core.raise/with-error.html)\\n and [`merge`](https://apidocs.arrow-kt.io/arrow-core/arrow.core.raise/merge.html).\\n- Adds [`NonEmptyCollection`](https://apidocs.arrow-kt.io/arrow-core/arrow.core/-non-empty-collection/index.html)\\n as common parent of [`NonEmptyList`](https://apidocs.arrow-kt.io/arrow-core/arrow.core/-non-empty-list/index.html)\\n and [`NonEmptySet`](https://apidocs.arrow-kt.io/arrow-core/arrow.core/-non-empty-set/index.html).\\n- Introduces [`arrow-core-serialization`](https://arrow-kt.io/learn/quickstart/serialization/)\\n to be used alongside KotlinX Serialization.\\n- Fixes a few issues found in the Release Candidate.\\n\\nRead more details in the full [Arrow 1.2.0 release announcement](https://xebia.com/blog/a-new-module-for-typed-errors-in-arrow-1-2-0/)."},{"id":"/2023/05/04/arrow-trajectory-kotlinconf","metadata":{"permalink":"/community/blog/2023/05/04/arrow-trajectory-kotlinconf","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-05-04-arrow-trajectory-kotlinconf.md","source":"@site/content/blog/2023-05-04-arrow-trajectory-kotlinconf.md","title":"Arrow 2.0\'s Trajectory - Video","description":"Watch Simon Vergauwen\'s presentation from KotlinConf 2023 about the history of Arrow, and the trajectory for Arrow 2.0.","date":"2023-05-04T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.09,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 2.0\'s Trajectory - Video","image":"https://img.youtube.com/vi/tplA17M9Y4Q/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/tplA17M9Y4Q","event":"KotlinConf"},"unlisted":false,"prevItem":{"title":"Arrow releases stable 1.2.0 version","permalink":"/community/blog/2023/07/12/arrow-1-2-0"},"nextItem":{"title":"Nicer data transformation with KopyKat and Optics","permalink":"/community/blog/2023/05/04/data-transformation-kotlinconf"}},"content":"Watch [Simon Vergauwen](https://twitter.com/vergauwen_simon)\'s presentation from KotlinConf 2023 about the history of Arrow, and the trajectory for Arrow 2.0."},{"id":"/2023/05/04/data-transformation-kotlinconf","metadata":{"permalink":"/community/blog/2023/05/04/data-transformation-kotlinconf","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-05-04-data-transformation-kotlinconf.md","source":"@site/content/blog/2023-05-04-data-transformation-kotlinconf.md","title":"Nicer data transformation with KopyKat and Optics","description":"Watch Alejandro Serrano\'s presentation from KotlinConf 2023 about data transformation.","date":"2023-05-04T00:00:00.000Z","tags":[{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.365,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Nicer data transformation with KopyKat and Optics","image":"https://img.youtube.com/vi/atV8liVgd3w/maxresdefault.jpg","category":"videos","tags":["optics","videos"],"link":"https://youtu.be/atV8liVgd3w","event":"KotlinConf"},"unlisted":false,"prevItem":{"title":"Arrow 2.0\'s Trajectory - Video","permalink":"/community/blog/2023/05/04/arrow-trajectory-kotlinconf"},"nextItem":{"title":"Typed Error Handling in Kotlin","permalink":"/community/blog/2023/04/17/typed-error-handling-in-kotlin"}},"content":"Watch [Alejandro Serrano](https://twitter.com/trupill)\'s presentation from KotlinConf 2023 about data transformation.\\n\\nData classes are incredibly useful when modeling our domain in an immutable way. The Kotlin compiler gives us many niceties, including \'copy\' to create a new value based on a previous one. However, this \'copy\' often falls short. This talk explores two alternatives: KopyKat, a plug-in to generate additional variations of \'copy\', and Arrow Optics, a whole framework to transform this immutable data."},{"id":"/2023/04/17/typed-error-handling-in-kotlin","metadata":{"permalink":"/community/blog/2023/04/17/typed-error-handling-in-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-04-17-typed-error-handling-in-kotlin.md","source":"@site/content/blog/2023-04-17-typed-error-handling-in-kotlin.md","title":"Typed Error Handling in Kotlin","description":"A comparative study about several typed-error handling practices in Kotlin.","date":"2023-04-17T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.585,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Typed Error Handling in Kotlin","image":"https://miro.medium.com/v2/resize:fit:4800/0*kOFUN-7oR7gyGXu_","category":"articles","tags":["core","articles"],"link":"https://medium.com/@mitchellyuwono/typed-error-handling-in-kotlin-11ff25882880"},"unlisted":false,"prevItem":{"title":"Nicer data transformation with KopyKat and Optics","permalink":"/community/blog/2023/05/04/data-transformation-kotlinconf"},"nextItem":{"title":"Arrow 2.0\'s Trajectory","permalink":"/community/blog/2023/04/16/arrow-2-0-trajectory"}},"content":"A comparative study about several typed-error handling practices in Kotlin.\\n\\nThere are various approaches to error handling in the Kotlin community. \\nIn this article we\u2019ve explored a small subset of typed error handling practices in the community. \\n\\nFrom the approaches explored, there were three patterns that aligns with Kotlin recommendation with \\nrelatively low cognitive complexity including: Sealed class matching with early returns, Arrow\'s `either { }` builder, \\nand Arrow\'s `context(Raise)` with context-receivers. \\n\\nArrow\'s `context(Raise)` achieved the most optimized score on all aspects of \\ndeveloper productivity. This includes having the lowest cognitive complexity, the lowest cyclomatic complexity \\nas well as the most succinct with the least lines of codes.\\n\\nRead the full article: [Typed Error Handling in Kotlin](https://medium.com/@mitchellyuwono/typed-error-handling-in-kotlin-11ff25882880)."},{"id":"/2023/04/16/arrow-2-0-trajectory","metadata":{"permalink":"/community/blog/2023/04/16/arrow-2-0-trajectory","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-04-16-arrow-2-0-trajectory.md","source":"@site/content/blog/2023-04-16-arrow-2-0-trajectory.md","title":"Arrow 2.0\'s Trajectory","description":"A full transcript and the slides from Simon Vergauwen\'s presentation from KotlinConf 2023 about the history of Arrow and where it\'s going.","date":"2023-04-16T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 2.0\'s Trajectory","image":"https://nomisrev.github.io/assets/KotlinConf%20-%20Arrow\'s%202.0%20Trajectory/KotlinConf%20-%20Arrow\'s%202.0%20Trajectory%20-%20Simon.001.png","category":"slidedecks","tags":["core","slidedecks"],"link":"https://nomisrev.github.io/arrows-2-0-trajectory/","event":"Kotlin Conf"},"unlisted":false,"prevItem":{"title":"Typed Error Handling in Kotlin","permalink":"/community/blog/2023/04/17/typed-error-handling-in-kotlin"},"nextItem":{"title":"Arrow 1.2.0-RC Release Summary","permalink":"/community/blog/2023/04/04/arrow-1-2-0-rc-summary"}},"content":"A full transcript and the slides from [Simon Vergauwen\'s](https://twitter.com/vergauwen_simon) presentation from KotlinConf 2023 about the history of Arrow and where it\'s going."},{"id":"/2023/04/04/arrow-1-2-0-rc-summary","metadata":{"permalink":"/community/blog/2023/04/04/arrow-1-2-0-rc-summary","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-04-04-arrow-1-2-0-rc-summary.md","source":"@site/content/blog/2023-04-04-arrow-1-2-0-rc-summary.md","title":"Arrow 1.2.0-RC Release Summary","description":"We\'re excited to announce Arrow 1.2.0-RC alongside a new Arrow website. To briefly summarize, this release:","date":"2023-04-04T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.27,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 1.2.0-RC Release Summary","image":"https://xebia.com/wp-content/uploads/2023/04/arrow-1-2-0-rc-twitter.jpg","category":"articles","tags":["core","articles"],"link":"https://xebia.com/blog/arrow-1-2-0-rc-is-now-available/"},"unlisted":false,"prevItem":{"title":"Arrow 2.0\'s Trajectory","permalink":"/community/blog/2023/04/16/arrow-2-0-trajectory"},"nextItem":{"title":"Functional Fun in Kotlin","permalink":"/community/blog/2023/02/04/functional-fun-kotlin"}},"content":"We\'re excited to announce Arrow 1.2.0-RC alongside a new Arrow website. To briefly summarize, this release:\\n\\n- Introduces a brand new [typed errors](http://arrow-kt.io/learn/typed-errors/working-with-typed-errors/) module.\\n- Adds more options for [resilience](http://arrow-kt.io/learn/resilience/).\\n- Marks every function and type we intend to remove in 2.0 as `@Deprecated`.\\n\\nRead more details in the full [Arrow 1.2.0 release announcement](https://xebia.com/blog/arrow-1-2-0-rc-is-now-available/)."},{"id":"/2023/02/04/functional-fun-kotlin","metadata":{"permalink":"/community/blog/2023/02/04/functional-fun-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-02-04-functional-fun-kotlin.md","source":"@site/content/blog/2023-02-04-functional-fun-kotlin.md","title":"Functional Fun in Kotlin","description":"Simon Vergauwen shares why he thinks Kotlin is great language to do modern functional programming, and why he believes it\'s perhaps the best language to do modern mainstream (hardcore) functional programming.","date":"2023-02-04T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks"}],"readingTime":0.155,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Fun in Kotlin","image":"https://files.speakerdeck.com/presentations/717144e6f3f54fd7aca2215fff36c2b3/preview_slide_0.jpg","category":"slidedecks","tags":["core","slidedecks"],"link":"https://speakerdeck.com/nomisrev/functional-fun-in-kotlin","event":"FOSDEM"},"unlisted":false,"prevItem":{"title":"Arrow 1.2.0-RC Release Summary","permalink":"/community/blog/2023/04/04/arrow-1-2-0-rc-summary"},"nextItem":{"title":"CodelyTV Interview with Raul Raja","permalink":"/community/blog/2023/01/03/codelytv-interview"}},"content":"[Simon Vergauwen](https://twitter.com/vergauwen_simon) shares why he thinks Kotlin is great language to do modern functional programming, and why he believes it\'s perhaps the best language to do modern mainstream (hardcore) functional programming."},{"id":"/2023/01/03/codelytv-interview","metadata":{"permalink":"/community/blog/2023/01/03/codelytv-interview","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2023-01-03-codelytv-interview.md","source":"@site/content/blog/2023-01-03-codelytv-interview.md","title":"CodelyTV Interview with Raul Raja","description":"An interview with Arrow maintainer Ra\xfal Raja by Rafa G\xf3mez on CodelyTV.","date":"2023-01-03T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"CodelyTV Interview with Raul Raja","image":"https://img.youtube.com/vi/8WdprhzmQe4/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/8WdprhzmQe4"},"unlisted":false,"prevItem":{"title":"Functional Fun in Kotlin","permalink":"/community/blog/2023/02/04/functional-fun-kotlin"},"nextItem":{"title":"Actions as Data","permalink":"/community/blog/2022/12/01/actions-as-data"}},"content":"An interview with Arrow maintainer Ra\xfal Raja by Rafa G\xf3mez on CodelyTV."},{"id":"/2022/12/01/actions-as-data","metadata":{"permalink":"/community/blog/2022/12/01/actions-as-data","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-actions-as-data.md","source":"@site/content/blog/2022-12-01-actions-as-data.md","title":"Actions as Data","description":"A presentation by Alejandro Serrano at Advanced Kotlin Dev Day 2022.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.055,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Actions as Data","image":"https://img.youtube.com/vi/ujzZITapUwA/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/ujzZITapUwA"},"unlisted":false,"prevItem":{"title":"CodelyTV Interview with Raul Raja","permalink":"/community/blog/2023/01/03/codelytv-interview"},"nextItem":{"title":"Context Receivers: Kotlin\'s new secret sauce","permalink":"/community/blog/2022/12/01/context-receivers"}},"content":"A presentation by Alejandro Serrano at Advanced Kotlin Dev Day 2022."},{"id":"/2022/12/01/context-receivers","metadata":{"permalink":"/community/blog/2022/12/01/context-receivers","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-context-receivers.md","source":"@site/content/blog/2022-12-01-context-receivers.md","title":"Context Receivers: Kotlin\'s new secret sauce","description":"Alejandro Serrano\'s presentation from Advanced Kotlin Dev Day 2022 about context receivers.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Context Receivers: Kotlin\'s new secret sauce","image":"https://img.youtube.com/vi/2oiRCYnqhDs/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/2oiRCYnqhDs"},"unlisted":false,"prevItem":{"title":"Actions as Data","permalink":"/community/blog/2022/12/01/actions-as-data"},"nextItem":{"title":"Functional Error Handling - A Practical Approach","permalink":"/community/blog/2022/12/01/functional-error-handling"}},"content":"Alejandro Serrano\'s presentation from Advanced Kotlin Dev Day 2022 about context receivers."},{"id":"/2022/12/01/functional-error-handling","metadata":{"permalink":"/community/blog/2022/12/01/functional-error-handling","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-functional-error-handling.md","source":"@site/content/blog/2022-12-01-functional-error-handling.md","title":"Functional Error Handling - A Practical Approach","description":"A presentation by Bas de Groot at Advanced Kotlin Dev Day 2022.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Error Handling - A Practical Approach","image":"https://img.youtube.com/vi/T04ynq2IVFs/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/T04ynq2IVFs"},"unlisted":false,"prevItem":{"title":"Context Receivers: Kotlin\'s new secret sauce","permalink":"/community/blog/2022/12/01/context-receivers"},"nextItem":{"title":"Functional Flowing","permalink":"/community/blog/2022/12/01/functional-flowing"}},"content":"A presentation by Bas de Groot at Advanced Kotlin Dev Day 2022."},{"id":"/2022/12/01/functional-flowing","metadata":{"permalink":"/community/blog/2022/12/01/functional-flowing","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-functional-flowing.md","source":"@site/content/blog/2022-12-01-functional-flowing.md","title":"Functional Flowing","description":"Simon Vergauwen shows how to leverage KotlinX Flow to describe powerful programs and build pipelines to transform and manipulate data in an efficient streaming way.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.125,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Flowing","image":"https://img.youtube.com/vi/Mj9B0rhN1RE/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/Mj9B0rhN1RE"},"unlisted":false,"prevItem":{"title":"Functional Error Handling - A Practical Approach","permalink":"/community/blog/2022/12/01/functional-error-handling"},"nextItem":{"title":"Graceful Shutdown with Structured Concurrency","permalink":"/community/blog/2022/12/01/graceful-shutdown-structured-concurrency"}},"content":"Simon Vergauwen shows how to leverage KotlinX Flow to describe powerful programs and build pipelines to transform and manipulate data in an efficient streaming way."},{"id":"/2022/12/01/graceful-shutdown-structured-concurrency","metadata":{"permalink":"/community/blog/2022/12/01/graceful-shutdown-structured-concurrency","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-12-01-graceful-shutdown-structured-concurrency.md","source":"@site/content/blog/2022-12-01-graceful-shutdown-structured-concurrency.md","title":"Graceful Shutdown with Structured Concurrency","description":"A presentation by Simon Vergauwen at Advanced Kotlin Dev Day 2022.","date":"2022-12-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.055,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Graceful Shutdown with Structured Concurrency","image":"https://img.youtube.com/vi/A69_t_oEP_E/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/A69_t_oEP_E"},"unlisted":false,"prevItem":{"title":"Functional Flowing","permalink":"/community/blog/2022/12/01/functional-flowing"},"nextItem":{"title":"Functional Programming in Kotlin: Exploring Arrow","permalink":"/community/blog/2022/07/01/exploring-arrow"}},"content":"A presentation by Simon Vergauwen at Advanced Kotlin Dev Day 2022."},{"id":"/2022/07/01/exploring-arrow","metadata":{"permalink":"/community/blog/2022/07/01/exploring-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-07-01-exploring-arrow.md","source":"@site/content/blog/2022-07-01-exploring-arrow.md","title":"Functional Programming in Kotlin: Exploring Arrow","description":"A presentation by Ties van de Veen at Voxxed Days Luxembourg 2022.","date":"2022-07-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Programming in Kotlin: Exploring Arrow","image":"https://img.youtube.com/vi/xxePZQlNyYY/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/xxePZQlNyYY"},"unlisted":false,"prevItem":{"title":"Graceful Shutdown with Structured Concurrency","permalink":"/community/blog/2022/12/01/graceful-shutdown-structured-concurrency"},"nextItem":{"title":"Turbocharging Kotlin: Arrow Analysis, Optics, and Meta","permalink":"/community/blog/2022/06/28/turbocharging-kotlin-talking-kotlin"}},"content":"A presentation by Ties van de Veen at Voxxed Days Luxembourg 2022."},{"id":"/2022/06/28/turbocharging-kotlin-talking-kotlin","metadata":{"permalink":"/community/blog/2022/06/28/turbocharging-kotlin-talking-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-06-28-turbocharging-kotlin-talking-kotlin.md","source":"@site/content/blog/2022-06-28-turbocharging-kotlin-talking-kotlin.md","title":"Turbocharging Kotlin: Arrow Analysis, Optics, and Meta","description":"Raul Raja, Simon Vergauwen, and Alejandro Serrano appeared on Talking Kotlin to chat about Arrow.","date":"2022-06-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"analysis","permalink":"/community/blog/tags/analysis"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.075,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Turbocharging Kotlin: Arrow Analysis, Optics, and Meta","image":"https://img.youtube.com/vi/tX4nLqcW2JA/maxresdefault.jpg","category":"videos","tags":["core","meta","optics","analysis","videos"],"link":"https://youtu.be/tX4nLqcW2JA"},"unlisted":false,"prevItem":{"title":"Functional Programming in Kotlin: Exploring Arrow","permalink":"/community/blog/2022/07/01/exploring-arrow"},"nextItem":{"title":"Arrow put on a big show at Kotlin Dev Day","permalink":"/community/blog/2022/06/14/arrow-kotlin-dev-day"}},"content":"Raul Raja, Simon Vergauwen, and Alejandro Serrano appeared on Talking Kotlin to chat about Arrow."},{"id":"/2022/06/14/arrow-kotlin-dev-day","metadata":{"permalink":"/community/blog/2022/06/14/arrow-kotlin-dev-day","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-06-14-arrow-kotlin-dev-day.md","source":"@site/content/blog/2022-06-14-arrow-kotlin-dev-day.md","title":"Arrow put on a big show at Kotlin Dev Day","description":"A recap of the attention Arrow received at Kotlin Dev Day.","date":"2022-06-14T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.055,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow put on a big show at Kotlin Dev Day","image":"https://www.47deg.com/assets/img/blog/featured_images/2022-06-13-arrow-put-on-big-show-at-kotlin-dev-day.jpg","category":"articles","tags":["core","fx","articles"],"link":"https://www.47deg.com/blog/arrow-put-on-big-show-at-kotlindevday/"},"unlisted":false,"prevItem":{"title":"Turbocharging Kotlin: Arrow Analysis, Optics, and Meta","permalink":"/community/blog/2022/06/28/turbocharging-kotlin-talking-kotlin"},"nextItem":{"title":"Building applications with Kotlin and Arrow.kt in style","permalink":"/community/blog/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style"}},"content":"A recap of the attention Arrow received at Kotlin Dev Day."},{"id":"/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style","metadata":{"permalink":"/community/blog/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-05-31-building-applications-with-kotlin-and-arrow-kt-in-style.md","source":"@site/content/blog/2022-05-31-building-applications-with-kotlin-and-arrow-kt-in-style.md","title":"Building applications with Kotlin and Arrow.kt in style","description":"A presentation by Simon Vergauwen presented on the official Kotlin YouTube channel.","date":"2022-05-31T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Building applications with Kotlin and Arrow.kt in style","image":"https://img.youtube.com/vi/g79A6HmbW5M/hqdefault.jpg","category":"videos","tags":["core","fx","videos"],"link":"https://youtu.be/g79A6HmbW5M"},"unlisted":false,"prevItem":{"title":"Arrow put on a big show at Kotlin Dev Day","permalink":"/community/blog/2022/06/14/arrow-kotlin-dev-day"},"nextItem":{"title":"Extending kotlinx.serialization functionality with Arrow Meta with Karin-Aleksandra Monoid","permalink":"/community/blog/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta"}},"content":"A presentation by Simon Vergauwen presented on the official Kotlin YouTube channel."},{"id":"/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta","metadata":{"permalink":"/community/blog/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-05-30-extending-kotlinx-serialization-functionality-arrow-meta.md","source":"@site/content/blog/2022-05-30-extending-kotlinx-serialization-functionality-arrow-meta.md","title":"Extending kotlinx.serialization functionality with Arrow Meta with Karin-Aleksandra Monoid","description":"Karin-Aleksandra Monoid provides an overview of Arrow Meta features.","date":"2022-05-30T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.045,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Extending kotlinx.serialization functionality with Arrow Meta with Karin-Aleksandra Monoid","image":"http://i3.ytimg.com/vi/eHSepXJPKZ0/hqdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://youtu.be/eHSepXJPKZ0","event":"Kotlin Dev Day"},"unlisted":false,"prevItem":{"title":"Building applications with Kotlin and Arrow.kt in style","permalink":"/community/blog/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style"},"nextItem":{"title":"Super-charge your build with Arrow Analysis by Alejandro Serrano Mena","permalink":"/community/blog/2022/05/30/super-charge-build-arrow-analysis"}},"content":"Karin-Aleksandra Monoid provides an overview of Arrow Meta features."},{"id":"/2022/05/30/super-charge-build-arrow-analysis","metadata":{"permalink":"/community/blog/2022/05/30/super-charge-build-arrow-analysis","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-05-30-super-charge-build-arrow-analysis.md","source":"@site/content/blog/2022-05-30-super-charge-build-arrow-analysis.md","title":"Super-charge your build with Arrow Analysis by Alejandro Serrano Mena","description":"Alejandro Serrano presents Arrow Analysis, a Kotlin compiler plug-in that does pre-and post-condition and type invariant checking at compile time.","date":"2022-05-30T00:00:00.000Z","tags":[{"label":"analysis","permalink":"/community/blog/tags/analysis"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.1,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Super-charge your build with Arrow Analysis by Alejandro Serrano Mena","image":"http://i3.ytimg.com/vi/yCZtnzTnpRA/hqdefault.jpg","category":"videos","tags":["analysis","videos"],"link":"https://youtu.be/yCZtnzTnpRA","event":"Kotlin Dev Day"},"unlisted":false,"prevItem":{"title":"Extending kotlinx.serialization functionality with Arrow Meta with Karin-Aleksandra Monoid","permalink":"/community/blog/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta"},"nextItem":{"title":"Functional programming in Kotlin: exploring Arrow by Ties Van de Ven","permalink":"/community/blog/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven"}},"content":"Alejandro Serrano presents Arrow Analysis, a Kotlin compiler plug-in that does pre-and post-condition and type invariant checking at compile time."},{"id":"/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven","metadata":{"permalink":"/community/blog/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-05-18-functional-programming-kotlin-exploring-arrow-ties-van-de-ven.md","source":"@site/content/blog/2022-05-18-functional-programming-kotlin-exploring-arrow-ties-van-de-ven.md","title":"Functional programming in Kotlin: exploring Arrow by Ties Van de Ven","description":"A talk by Ties van de Ven that shows how Arrow helps to unleash the full FP power of Kotlin.","date":"2022-05-18T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.1,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional programming in Kotlin: exploring Arrow by Ties Van de Ven","image":"http://i3.ytimg.com/vi/eFheAErqJzA/hqdefault.jpg","category":"videos","tags":["core","optics","videos"],"link":"https://youtu.be/eFheAErqJzA","event":"Devoxx UK"},"unlisted":false,"prevItem":{"title":"Super-charge your build with Arrow Analysis by Alejandro Serrano Mena","permalink":"/community/blog/2022/05/30/super-charge-build-arrow-analysis"},"nextItem":{"title":"Domain Model Validation In Kotlin: Part 4","permalink":"/community/blog/2022/03/31/domain-model-validation-in-kotlin-part-4"}},"content":"A talk by Ties van de Ven that shows how Arrow helps to unleash the full FP power of Kotlin."},{"id":"/2022/03/31/domain-model-validation-in-kotlin-part-4","metadata":{"permalink":"/community/blog/2022/03/31/domain-model-validation-in-kotlin-part-4","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-03-31-domain-model-validation-in-kotlin-part-4.md","source":"@site/content/blog/2022-03-31-domain-model-validation-in-kotlin-part-4.md","title":"Domain Model Validation In Kotlin: Part 4","description":"In this final part of the series, Tiberiu puts everything together in a small CLI application, using Arrow data types and computation blocks","date":"2022-03-31T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Domain Model Validation In Kotlin: Part 4","image":"https://miro.medium.com/max/1400/1*3jegLLY4GbGj71nauV2l_Q.png","category":"articles","tags":["core","articles"],"link":"https://tibtof.medium.com/domain-model-validation-in-kotlin-part-4-2462b334ca6c"},"unlisted":false,"prevItem":{"title":"Functional programming in Kotlin: exploring Arrow by Ties Van de Ven","permalink":"/community/blog/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven"},"nextItem":{"title":"Domain Model Validation In Kotlin: Part 3","permalink":"/community/blog/2022/03/10/domain-model-validation-in-kotlin-part-3"}},"content":"In this final part of the series, Tiberiu puts everything together in a small CLI application, using Arrow data types and computation blocks\\nto handle validation errors and exceptions in a unitary and composable way."},{"id":"/2022/03/10/domain-model-validation-in-kotlin-part-3","metadata":{"permalink":"/community/blog/2022/03/10/domain-model-validation-in-kotlin-part-3","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-03-10-domain-model-validation-in-kotlin-part-3.md","source":"@site/content/blog/2022-03-10-domain-model-validation-in-kotlin-part-3.md","title":"Domain Model Validation In Kotlin: Part 3","description":"In the third part of the series, Tiberiu Tofan explores multiple techniques of using a context when doing validations","date":"2022-03-10T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.2,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Domain Model Validation In Kotlin: Part 3","image":"https://miro.medium.com/max/1400/1*6RXLldOxvMR3nKi_k_wYTA.png","category":"articles","tags":["core","articles"],"link":"https://tibtof.medium.com/domain-model-validation-in-kotlin-part-3-96c3fd4af342"},"unlisted":false,"prevItem":{"title":"Domain Model Validation In Kotlin: Part 4","permalink":"/community/blog/2022/03/31/domain-model-validation-in-kotlin-part-4"},"nextItem":{"title":"Domain Model Validation In Kotlin: Part 2","permalink":"/community/blog/2022/03/03/domain-model-validation-in-kotlin-part-2"}},"content":"In the third part of the series, Tiberiu Tofan explores multiple techniques of using a context when doing validations \\nand how the context can be changed in the tests to simulate success or failure. All using just Kotlin standard library."},{"id":"/2022/03/03/domain-model-validation-in-kotlin-part-2","metadata":{"permalink":"/community/blog/2022/03/03/domain-model-validation-in-kotlin-part-2","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-03-03-domain-model-validation-in-kotlin-part-2.md","source":"@site/content/blog/2022-03-03-domain-model-validation-in-kotlin-part-2.md","title":"Domain Model Validation In Kotlin: Part 2","description":"In the second article in this series, Tiberiu Tofan writes how Validated type can be","date":"2022-03-03T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.195,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Domain Model Validation In Kotlin: Part 2","image":"https://miro.medium.com/max/1400/1*vf0byE6Kp5wGwmDqxRbUOg.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/@tibtof/domain-model-validation-in-kotlin-part-2-fb4726ef8f8d"},"unlisted":false,"prevItem":{"title":"Domain Model Validation In Kotlin: Part 3","permalink":"/community/blog/2022/03/10/domain-model-validation-in-kotlin-part-3"},"nextItem":{"title":"Domain Model Validation In Kotlin: Part 1","permalink":"/community/blog/2022/02/22/domain-model-validation-in-kotlin-part-1"}},"content":"In the second article in this series, Tiberiu Tofan writes how Validated type can be \\nused to validate multiple properties, accumulate the errors, apply individual \\nelement validations to lists of elements, and create rules that \\ndepend on numerous properties."},{"id":"/2022/02/22/domain-model-validation-in-kotlin-part-1","metadata":{"permalink":"/community/blog/2022/02/22/domain-model-validation-in-kotlin-part-1","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-02-22-domain-model-validation-in-kotlin-part-1.md","source":"@site/content/blog/2022-02-22-domain-model-validation-in-kotlin-part-1.md","title":"Domain Model Validation In Kotlin: Part 1","description":"In the first article in this series, Tiberiu Tofan describes his team\'s journey using Kotlin and Arrow for domain model validation,","date":"2022-02-22T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.16,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Domain Model Validation In Kotlin: Part 1","image":"https://miro.medium.com/max/1400/1*Xc0B4542z3WHiQ3DvLXcYg.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/@tibtof/domain-model-validation-in-kotlin-part-1-21fa44c60ef3"},"unlisted":false,"prevItem":{"title":"Domain Model Validation In Kotlin: Part 2","permalink":"/community/blog/2022/03/03/domain-model-validation-in-kotlin-part-2"},"nextItem":{"title":"Announcing Arrow Analysis - a Kotlin compiler plug-in","permalink":"/community/blog/2022/02/02/announcing-arrow-analysis"}},"content":"In the first article in this series, Tiberiu Tofan describes his team\'s journey using Kotlin and Arrow for domain model validation, \\nstarting by setting the domain model\'s foundation in a type-safe way."},{"id":"/2022/02/02/announcing-arrow-analysis","metadata":{"permalink":"/community/blog/2022/02/02/announcing-arrow-analysis","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2022-02-02-announcing-arrow-analysis.md","source":"@site/content/blog/2022-02-02-announcing-arrow-analysis.md","title":"Announcing Arrow Analysis - a Kotlin compiler plug-in","description":"Announcing Arrow Analysis - a Kotlin compiler plug-in.","date":"2022-02-02T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.04,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Announcing Arrow Analysis - a Kotlin compiler plug-in","image":"https://www.47deg.com/assets/img/blog/featured_images/2022-01-25-arrow-analysis-is-available.jpg","category":"articles","tags":["meta","articles"],"link":"https://www.47deg.com/blog/arrow-analysis-kotlin-compiler-plugin/"},"unlisted":false,"prevItem":{"title":"Domain Model Validation In Kotlin: Part 1","permalink":"/community/blog/2022/02/22/domain-model-validation-in-kotlin-part-1"},"nextItem":{"title":"Functional programming in Kotlin with Arrow","permalink":"/community/blog/2021/12/15/functional-programming-in-kotlin-with-arrow"}},"content":"Announcing Arrow Analysis - a Kotlin compiler plug-in."},{"id":"/2021/12/15/functional-programming-in-kotlin-with-arrow","metadata":{"permalink":"/community/blog/2021/12/15/functional-programming-in-kotlin-with-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-12-15-functional-programming-in-kotlin-with-arrow.md","source":"@site/content/blog/2021-12-15-functional-programming-in-kotlin-with-arrow.md","title":"Functional programming in Kotlin with Arrow","description":"A presentation by Simon Vergauwen and Alejandro Serrano presented on the official Kotlin YouTube channel.","date":"2021-12-15T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.075,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional programming in Kotlin with Arrow","image":"https://img.youtube.com/vi/IDMmmrRhUvQ/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/IDMmmrRhUvQ"},"unlisted":false,"prevItem":{"title":"Announcing Arrow Analysis - a Kotlin compiler plug-in","permalink":"/community/blog/2022/02/02/announcing-arrow-analysis"},"nextItem":{"title":"Functional programming in Kotlin: Exploring Arrow","permalink":"/community/blog/2021/11/30/functional-programming-kotlin-exploring-arrow"}},"content":"A presentation by Simon Vergauwen and Alejandro Serrano presented on the official Kotlin YouTube channel."},{"id":"/2021/11/30/functional-programming-kotlin-exploring-arrow","metadata":{"permalink":"/community/blog/2021/11/30/functional-programming-kotlin-exploring-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-11-30-functional-programming-kotlin-exploring-arrow.md","source":"@site/content/blog/2021-11-30-functional-programming-kotlin-exploring-arrow.md","title":"Functional programming in Kotlin: Exploring Arrow","description":"A talk by Ties van de Ven explaining how to use the Either monad in practice, and how to use Arrow Optics lenses.","date":"2021-11-30T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.115,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional programming in Kotlin: Exploring Arrow","image":"http://i3.ytimg.com/vi/Wojgv2MeMGU/hqdefault.jpg","category":"videos","tags":["core","optics","videos"],"link":"https://youtu.be/Wojgv2MeMGU","event":"Kotlin Dev Day Amsterdam"},"unlisted":false,"prevItem":{"title":"Functional programming in Kotlin with Arrow","permalink":"/community/blog/2021/12/15/functional-programming-in-kotlin-with-arrow"},"nextItem":{"title":"Arrow of Outrageous Error Handling","permalink":"/community/blog/2021/08/12/arrow-of-outrageous-error-handling"}},"content":"A talk by Ties van de Ven explaining how to use the Either monad in practice, and how to use Arrow Optics lenses."},{"id":"/2021/08/12/arrow-of-outrageous-error-handling","metadata":{"permalink":"/community/blog/2021/08/12/arrow-of-outrageous-error-handling","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-08-12-arrow-of-outrageous-error-handling.md","source":"@site/content/blog/2021-08-12-arrow-of-outrageous-error-handling.md","title":"Arrow of Outrageous Error Handling","description":"An Android Worldwide talk by David Rawson about error handling on Android using Arrow.","date":"2021-08-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow of Outrageous Error Handling","image":"http://i3.ytimg.com/vi/OiN79vpPM08/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/OiN79vpPM08","event":"Android Worldwide"},"unlisted":false,"prevItem":{"title":"Functional programming in Kotlin: Exploring Arrow","permalink":"/community/blog/2021/11/30/functional-programming-kotlin-exploring-arrow"},"nextItem":{"title":"Functional Domain Modeling in Kotlin - Validation","permalink":"/community/blog/2021/04/13/functional-domain-modeling-kotlin-validation"}},"content":"An Android Worldwide talk by David Rawson about error handling on Android using Arrow."},{"id":"/2021/04/13/functional-domain-modeling-kotlin-validation","metadata":{"permalink":"/community/blog/2021/04/13/functional-domain-modeling-kotlin-validation","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-04-13-functional-domain-modeling-kotlin-validation.md","source":"@site/content/blog/2021-04-13-functional-domain-modeling-kotlin-validation.md","title":"Functional Domain Modeling in Kotlin - Validation","description":"In part two of Functional Domain Modeling in Kotlin, Simon Vergauwen shows how to improve a domain with validation.","date":"2021-04-13T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.095,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Domain Modeling in Kotlin - Validation","image":"https://www.47deg.com/assets/img/blog/featured_images/2021-04-07-functional-domain-modeling-in-kotlin-validation.jpg","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/functional-domain-modeling-part-2/"},"unlisted":false,"prevItem":{"title":"Arrow of Outrageous Error Handling","permalink":"/community/blog/2021/08/12/arrow-of-outrageous-error-handling"},"nextItem":{"title":"Functional Domain Modeling in Kotlin","permalink":"/community/blog/2021/04/11/functional-domain-modeling-kotlin"}},"content":"In part two of Functional Domain Modeling in Kotlin, Simon Vergauwen shows how to improve a domain with validation."},{"id":"/2021/04/11/functional-domain-modeling-kotlin","metadata":{"permalink":"/community/blog/2021/04/11/functional-domain-modeling-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-04-11-functional-domain-modeling-kotlin.md","source":"@site/content/blog/2021-04-11-functional-domain-modeling-kotlin.md","title":"Functional Domain Modeling in Kotlin","description":"Learn how to leverage Functional Domain Modeling to fully utilize the Kotlin type system and prevent bugs.","date":"2021-04-11T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.085,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Domain Modeling in Kotlin","image":"https://www.47deg.com/assets/img/blog/featured_images/2021-02-05-functional-domain-modeling-in-kotlin.jpg","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/functional-domain-modeling/"},"unlisted":false,"prevItem":{"title":"Functional Domain Modeling in Kotlin - Validation","permalink":"/community/blog/2021/04/13/functional-domain-modeling-kotlin-validation"},"nextItem":{"title":"Your own custom Spring Data repository","permalink":"/community/blog/2021/04/11/your-own-custom-spring-data-repository"}},"content":"Learn how to leverage Functional Domain Modeling to fully utilize the Kotlin type system and prevent bugs."},{"id":"/2021/04/11/your-own-custom-spring-data-repository","metadata":{"permalink":"/community/blog/2021/04/11/your-own-custom-spring-data-repository","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-04-11-your-own-custom-spring-data-repository.md","source":"@site/content/blog/2021-04-11-your-own-custom-spring-data-repository.md","title":"Your own custom Spring Data repository","description":"How to integrate Spring Data Repository with Arrow.","date":"2021-04-11T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.04,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Your own custom Spring Data repository","image":"https://blog.frankel.ch/assets/resources/custom-spring-data-repository/spring-data.svg","category":"articles","tags":["core","articles"],"link":"https://blog.frankel.ch/custom-spring-data-repository/"},"unlisted":false,"prevItem":{"title":"Functional Domain Modeling in Kotlin","permalink":"/community/blog/2021/04/11/functional-domain-modeling-kotlin"},"nextItem":{"title":"Arrow 0.12.0 & 0.13.1 are now available","permalink":"/community/blog/2021/04/01/arrow-0-12-0-0-13-1-release"}},"content":"How to integrate Spring Data Repository with Arrow."},{"id":"/2021/04/01/arrow-0-12-0-0-13-1-release","metadata":{"permalink":"/community/blog/2021/04/01/arrow-0-12-0-0-13-1-release","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-04-01-arrow-0-12-0-0-13-1-release.md","source":"@site/content/blog/2021-04-01-arrow-0-12-0-0-13-1-release.md","title":"Arrow 0.12.0 & 0.13.1 are now available","description":"Arrow 0.12.0 & 0.13.1 are now available, featuring streamlining of the library for 1.0.0.","date":"2021-04-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 0.12.0 & 0.13.1 are now available","image":"https://www.47deg.com/assets/img/blog/featured_images/2021-03-30-arrow-0-13-1.jpg","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/arrow-0.13.0-release/"},"unlisted":false,"prevItem":{"title":"Your own custom Spring Data repository","permalink":"/community/blog/2021/04/11/your-own-custom-spring-data-repository"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Shiny Things","permalink":"/community/blog/2021/02/26/advanced-fp-enterprise-bee-shiny-things"}},"content":"Arrow 0.12.0 & 0.13.1 are now available, featuring streamlining of the library for 1.0.0."},{"id":"/2021/02/26/advanced-fp-enterprise-bee-shiny-things","metadata":{"permalink":"/community/blog/2021/02/26/advanced-fp-enterprise-bee-shiny-things","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-26-advanced-fp-enterprise-bee-shiny-things.md","source":"@site/content/blog/2021-02-26-advanced-fp-enterprise-bee-shiny-things.md","title":"Advanced FP for the Enterprise Bee: Shiny Things","description":"Garth Gilmour concludes his 8-part series introducing advanced FP concepts via Kotlin and Arrow.","date":"2021-02-26T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Shiny Things","image":"https://miro.medium.com/max/675/0*2D7qyemVVsa0Aldp.jpg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-shiny-things-770ae9c27472"},"unlisted":false,"prevItem":{"title":"Arrow 0.12.0 & 0.13.1 are now available","permalink":"/community/blog/2021/04/01/arrow-0-12-0-0-13-1-release"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: State","permalink":"/community/blog/2021/02/19/advanced-fp-enterprise-bee-state"}},"content":"Garth Gilmour concludes his 8-part series introducing advanced FP concepts via Kotlin and Arrow."},{"id":"/2021/02/19/advanced-fp-enterprise-bee-state","metadata":{"permalink":"/community/blog/2021/02/19/advanced-fp-enterprise-bee-state","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-19-advanced-fp-enterprise-bee-state.md","source":"@site/content/blog/2021-02-19-advanced-fp-enterprise-bee-state.md","title":"Advanced FP for the Enterprise Bee: State","description":"This is the seventh post in a series written by Garth Gilmour introducing advanced FP concepts via Kotlin and Arrow. This article explores the world of Monads, and, in particular, the State type.","date":"2021-02-19T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.165,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: State","image":"https://miro.medium.com/max/460/0*rMk9skNj5L-1E6cs","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-state-4f8fd2d8098b"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Shiny Things","permalink":"/community/blog/2021/02/26/advanced-fp-enterprise-bee-shiny-things"},"nextItem":{"title":"Hands-on Arrow","permalink":"/community/blog/2021/02/12/hands-on-arrow"}},"content":"This is the seventh post in a series written by Garth Gilmour introducing advanced FP concepts via Kotlin and Arrow. This article explores the world of Monads, and, in particular, the State type."},{"id":"/2021/02/12/hands-on-arrow","metadata":{"permalink":"/community/blog/2021/02/12/hands-on-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-12-hands-on-arrow.md","source":"@site/content/blog/2021-02-12-hands-on-arrow.md","title":"Hands-on Arrow","description":"A video from the meetup of the Google Developer Group based in Nuremberg with a presentation by Karin-Aleksandra Monoid about using Arrow.","date":"2021-02-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Hands-on Arrow","image":"http://i3.ytimg.com/vi/tkl9EaUMfm8/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/tkl9EaUMfm8?t=2136","event":"GDG Nuremberg"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: State","permalink":"/community/blog/2021/02/19/advanced-fp-enterprise-bee-state"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Optics","permalink":"/community/blog/2021/02/10/advanced-fp-enterprise-bee-optics"}},"content":"A video from the meetup of the Google Developer Group based in Nuremberg with a presentation by Karin-Aleksandra Monoid about using Arrow."},{"id":"/2021/02/10/advanced-fp-enterprise-bee-optics","metadata":{"permalink":"/community/blog/2021/02/10/advanced-fp-enterprise-bee-optics","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-10-advanced-fp-enterprise-bee-optics.md","source":"@site/content/blog/2021-02-10-advanced-fp-enterprise-bee-optics.md","title":"Advanced FP for the Enterprise Bee: Optics","description":"This is the sixth post in a series introducing advanced FP concepts via Kotlin and Arrow. This article covers Optics with Kotlin and Arrow.","date":"2021-02-10T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.12,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Optics","image":"https://miro.medium.com/max/700/1*7Q3EXosiX4YmLGYQWOllmQ.jpeg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-optics-2ccc444d409b"},"unlisted":false,"prevItem":{"title":"Hands-on Arrow","permalink":"/community/blog/2021/02/12/hands-on-arrow"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Typeclasses","permalink":"/community/blog/2021/02/05/advanced-fp-enterprise-bee-typeclasses"}},"content":"This is the sixth post in a series introducing advanced FP concepts via Kotlin and Arrow. This article covers Optics with Kotlin and Arrow."},{"id":"/2021/02/05/advanced-fp-enterprise-bee-typeclasses","metadata":{"permalink":"/community/blog/2021/02/05/advanced-fp-enterprise-bee-typeclasses","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-02-05-advanced-fp-enterprise-bee-typeclasses.md","source":"@site/content/blog/2021-02-05-advanced-fp-enterprise-bee-typeclasses.md","title":"Advanced FP for the Enterprise Bee: Typeclasses","description":"This fifth post in a series introduces advanced FP concepts via Kotlin and Arrow. This article introduces Typeclasses, and reviews a practical example of Typeclasses from the Arrow library.","date":"2021-02-05T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.145,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Typeclasses","image":"https://miro.medium.com/max/700/0*oOFUf_kkNWyHzS8Q.jpg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-typeclasses-2addc232ae23"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Optics","permalink":"/community/blog/2021/02/10/advanced-fp-enterprise-bee-optics"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Kleisli","permalink":"/community/blog/2021/01/29/advanced-fp-enterprise-bee-kleisli"}},"content":"This fifth post in a series introduces advanced FP concepts via Kotlin and Arrow. This article introduces Typeclasses, and reviews a practical example of Typeclasses from the Arrow library."},{"id":"/2021/01/29/advanced-fp-enterprise-bee-kleisli","metadata":{"permalink":"/community/blog/2021/01/29/advanced-fp-enterprise-bee-kleisli","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-29-advanced-fp-enterprise-bee-kleisli.md","source":"@site/content/blog/2021-01-29-advanced-fp-enterprise-bee-kleisli.md","title":"Advanced FP for the Enterprise Bee: Kleisli","description":"This fourth post in a series introduces advanced FP concepts via Kotlin and Arrow. This article looks at the Kleisli type.","date":"2021-01-29T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.105,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Kleisli","image":"https://miro.medium.com/max/397/1*ALuwNIY0UvXaBzk_zaBXTA.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-kleisli-1d0de0fa82d9"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Typeclasses","permalink":"/community/blog/2021/02/05/advanced-fp-enterprise-bee-typeclasses"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Higher Kinded Types","permalink":"/community/blog/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types"}},"content":"This fourth post in a series introduces advanced FP concepts via Kotlin and Arrow. This article looks at the Kleisli type."},{"id":"/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types","metadata":{"permalink":"/community/blog/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-22-advanced-fp-enterprise-bee-higher-kinded-types.md","source":"@site/content/blog/2021-01-22-advanced-fp-enterprise-bee-higher-kinded-types.md","title":"Advanced FP for the Enterprise Bee: Higher Kinded Types","description":"This third post in a series introduces advanced FP concepts via Kotlin and Arrow. This article shows the usefulness of Higher Kinded Types.","date":"2021-01-22T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.115,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Higher Kinded Types","image":"https://miro.medium.com/max/700/0*cXrhKidxYGGJABB1.jpg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-higher-kinded-types-c6742e24527"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Kleisli","permalink":"/community/blog/2021/01/29/advanced-fp-enterprise-bee-kleisli"},"nextItem":{"title":"FP concepts with Arrow","permalink":"/community/blog/2021/01/20/fp-concepts-with-arrow"}},"content":"This third post in a series introduces advanced FP concepts via Kotlin and Arrow. This article shows the usefulness of Higher Kinded Types."},{"id":"/2021/01/20/fp-concepts-with-arrow","metadata":{"permalink":"/community/blog/2021/01/20/fp-concepts-with-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-20-fp-concepts-with-arrow.md","source":"@site/content/blog/2021-01-20-fp-concepts-with-arrow.md","title":"FP concepts with Arrow","description":"A video from the Belfast Kotlin User Group with a presentation by Katie Levy and Shelby Cohen covering FP concepts with Arrow.","date":"2021-01-20T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"FP concepts with Arrow","image":"http://i3.ytimg.com/vi/IZlMQXLySz4/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/IZlMQXLySz4","event":"Belfast KUG"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Higher Kinded Types","permalink":"/community/blog/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Applicatives","permalink":"/community/blog/2021/01/15/advanced-fp-enterprise-bee-applicatives"}},"content":"A video from the Belfast Kotlin User Group with a presentation by Katie Levy and Shelby Cohen covering FP concepts with Arrow."},{"id":"/2021/01/15/advanced-fp-enterprise-bee-applicatives","metadata":{"permalink":"/community/blog/2021/01/15/advanced-fp-enterprise-bee-applicatives","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-15-advanced-fp-enterprise-bee-applicatives.md","source":"@site/content/blog/2021-01-15-advanced-fp-enterprise-bee-applicatives.md","title":"Advanced FP for the Enterprise Bee: Applicatives","description":"This second post in a series introduces advanced FP concepts via Kotlin and Arrow. This article takes a deep dive into Applicatives.","date":"2021-01-15T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Applicatives","image":"https://miro.medium.com/max/650/0*M1mKM3l9OCuW5bgC.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-applicatives-be76e4b6803c"},"unlisted":false,"prevItem":{"title":"FP concepts with Arrow","permalink":"/community/blog/2021/01/20/fp-concepts-with-arrow"},"nextItem":{"title":"Functional Android","permalink":"/community/blog/2021/01/13/functional-android"}},"content":"This second post in a series introduces advanced FP concepts via Kotlin and Arrow. This article takes a deep dive into Applicatives."},{"id":"/2021/01/13/functional-android","metadata":{"permalink":"/community/blog/2021/01/13/functional-android","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-13-functional-android.md","source":"@site/content/blog/2021-01-13-functional-android.md","title":"Functional Android","description":"In this talk from the January 13th, 2021 Kotlin London User Group meetup, Jorge Castillo shows how to seamlessly integrate the functional programming paradigm with our Android architecture to get the most out of both worlds.","date":"2021-01-13T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Android","image":"https://www.47deg.com/assets/img/events/featured_images/2021-01-13-kotlin-london-meetup.jpg","category":"videos","tags":["fx","videos"],"link":"https://youtu.be/XhijgrEG1tI","event":"Kotlin London"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Applicatives","permalink":"/community/blog/2021/01/15/advanced-fp-enterprise-bee-applicatives"},"nextItem":{"title":"Advanced FP for the Enterprise Bee: Traverse","permalink":"/community/blog/2021/01/08/advanced-fp-enterprise-bee-traverse"}},"content":"In this talk from the January 13th, 2021 Kotlin London User Group meetup, Jorge Castillo shows how to seamlessly integrate the functional programming paradigm with our Android architecture to get the most out of both worlds."},{"id":"/2021/01/08/advanced-fp-enterprise-bee-traverse","metadata":{"permalink":"/community/blog/2021/01/08/advanced-fp-enterprise-bee-traverse","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2021-01-08-advanced-fp-enterprise-bee-traverse.md","source":"@site/content/blog/2021-01-08-advanced-fp-enterprise-bee-traverse.md","title":"Advanced FP for the Enterprise Bee: Traverse","description":"This first post in a series introduces advanced FP concepts via Kotlin and Arrow. This article takes a deep dive into the Traverse operation.","date":"2021-01-08T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.12,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Advanced FP for the Enterprise Bee: Traverse","image":"https://miro.medium.com/max/700/1*GAhKVPMXbQExcEhYho3XzQ.jpeg","category":"articles","tags":["core","articles"],"link":"https://medium.com/google-developer-experts/advanced-fp-for-the-enterprise-bee-traverse-b5e4e8b7b8e4"},"unlisted":false,"prevItem":{"title":"Functional Android","permalink":"/community/blog/2021/01/13/functional-android"},"nextItem":{"title":"Roll your own Computation blocks in Kotlin","permalink":"/community/blog/2020/12/16/roll-your-own-computation-blocks-kotlin"}},"content":"This first post in a series introduces advanced FP concepts via Kotlin and Arrow. This article takes a deep dive into the Traverse operation."},{"id":"/2020/12/16/roll-your-own-computation-blocks-kotlin","metadata":{"permalink":"/community/blog/2020/12/16/roll-your-own-computation-blocks-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-12-16-roll-your-own-computation-blocks-kotlin.md","source":"@site/content/blog/2020-12-16-roll-your-own-computation-blocks-kotlin.md","title":"Roll your own Computation blocks in Kotlin","description":"Computation blocks empower library authors and users to build ad-hoc operators and DSLs over any data-type getting rid of API complexity and simplifying composition. In this talk, we will learn how we can build Computation blocks over Kotlin suspend functions & the Arrow Continuations library\'s reset / shift capabilities. We will demonstrate the composition of well known JVM data-types and patterns such as lists, futures, streams, and IOs, where callback chains can be simply replaced by a single","date":"2020-12-16T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.71,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Roll your own Computation blocks in Kotlin","image":"https://img.youtube.com/vi/0_zatebXMDU/hqdefault.jpg","category":"videos","tags":["core","fx","videos"],"link":"https://youtu.be/0_zatebXMDU","event":"Lambda Lille"},"unlisted":false,"prevItem":{"title":"Advanced FP for the Enterprise Bee: Traverse","permalink":"/community/blog/2021/01/08/advanced-fp-enterprise-bee-traverse"},"nextItem":{"title":"Fight Complexity with Functional Programming","permalink":"/community/blog/2020/11/19/fight-complexity-with-functional-programming"}},"content":"Computation blocks empower library authors and users to build ad-hoc operators and DSLs over any data-type getting rid of API complexity and simplifying composition. In this talk, we will learn how we can build Computation blocks over Kotlin suspend functions & the Arrow Continuations library\'s `reset` / `shift` capabilities. We will demonstrate the composition of well known JVM data-types and patterns such as lists, futures, streams, and IOs, where callback chains can be simply replaced by a single\\nsuspended operator. The Kotlin suspension system provides enough capabilities to implement delimited continuations allowing us to ignore methods such as `map` & `flatMap` on your favorite data-type in favor of direct imperative syntax. Leveraging Kotlin suspension & thinking of Continuations as \\"The Mother of all Monads\\", we will embark on this journey where we\'ll build and roll our own computation blocks with Arrow Continuations."},{"id":"/2020/11/19/fight-complexity-with-functional-programming","metadata":{"permalink":"/community/blog/2020/11/19/fight-complexity-with-functional-programming","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-11-19-fight-complexity-with-functional-programming.md","source":"@site/content/blog/2020-11-19-fight-complexity-with-functional-programming.md","title":"Fight Complexity with Functional Programming","description":"A Metric-driven approach to reduce Cognitive Complexity in a code base, using Functional Programming, demoed hands-on, by solving a complex real-world ubiquitous design challenge - REST API Bulk Request Validation, with an extensible Framework that separates what-to-do (Validations) from how-to-do (Validation Orchestration). Let\'s do a case study of a successful implementation done by our team in the world\'s largest SaaS org, Salesforce, using Kotlin and Arrow.","date":"2020-11-19T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.33,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Fight Complexity with Functional Programming","image":"https://img.youtube.com/vi/Dvr6gx4XaD8/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/Dvr6gx4XaD8","event":"All Things Open 2020"},"unlisted":false,"prevItem":{"title":"Roll your own Computation blocks in Kotlin","permalink":"/community/blog/2020/12/16/roll-your-own-computation-blocks-kotlin"},"nextItem":{"title":"Arrow Promoted to Adopt by Technology Radar","permalink":"/community/blog/2020/10/28/arrow-promoted-to-adopt"}},"content":"A Metric-driven approach to reduce Cognitive Complexity in a code base, using Functional Programming, demoed hands-on, by solving a complex real-world ubiquitous design challenge - REST API Bulk Request Validation, with an extensible Framework that separates what-to-do (Validations) from how-to-do (Validation Orchestration). Let\'s do a case study of a successful implementation done by our team in the world\'s largest SaaS org, Salesforce, using Kotlin and Arrow."},{"id":"/2020/10/28/arrow-promoted-to-adopt","metadata":{"permalink":"/community/blog/2020/10/28/arrow-promoted-to-adopt","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-10-28-arrow-promoted-to-adopt.md","source":"@site/content/blog/2020-10-28-arrow-promoted-to-adopt.md","title":"Arrow Promoted to Adopt by Technology Radar","description":"Arrow is promoted as the functional companion for Kotlin\'s standard library. Indeed, the package of ready-to-use higher-level abstractions delivered by Arrow has proven so useful that our teams now consider Arrow a sensible default when working with Kotlin. Recently, in preparation for the 1.0 release, the Arrow team introduced several changes, including the addition of new modules but also some deprecations and removals.","date":"2020-10-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.315,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Promoted to Adopt by Technology Radar","image":"https://static.thoughtworks.com/images/radar/2020-10/en/tech-radar-card.png","category":"articles","tags":["core","articles"],"link":"https://www.thoughtworks.com/radar/languages-and-frameworks/arrow"},"unlisted":false,"prevItem":{"title":"Fight Complexity with Functional Programming","permalink":"/community/blog/2020/11/19/fight-complexity-with-functional-programming"},"nextItem":{"title":"How to fix the pain of modifying Kotlin nested data classes","permalink":"/community/blog/2020/10/28/modifying-kotlin-nested-data-classes"}},"content":"Arrow is promoted as the functional companion for Kotlin\'s standard library. Indeed, the package of ready-to-use higher-level abstractions delivered by Arrow has proven so useful that our teams now consider Arrow a sensible default when working with Kotlin. Recently, in preparation for the 1.0 release, the Arrow team introduced several changes, including the addition of new modules but also some deprecations and removals."},{"id":"/2020/10/28/modifying-kotlin-nested-data-classes","metadata":{"permalink":"/community/blog/2020/10/28/modifying-kotlin-nested-data-classes","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-10-28-modifying-kotlin-nested-data-classes.md","source":"@site/content/blog/2020-10-28-modifying-kotlin-nested-data-classes.md","title":"How to fix the pain of modifying Kotlin nested data classes","description":"Lenses are not part of the Kotlin Standard Library yet, so we will need to use an Open Source library called Arrow-kt. Arrow-kt is a huge community effort to bring some of the missing functional programming features to Kotlin.","date":"2020-10-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.195,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"How to fix the pain of modifying Kotlin nested data classes","image":"https://i2.wp.com/ivanmorgillo.com/wp-content/uploads/2020/10/pexels-photo-712786.jpeg","category":"articles","tags":["core","articles"],"link":"https://ivanmorgillo.com/2020/10/28/how-to-fix-the-pain-of-modifying-kotlin-nested-data-classes/"},"unlisted":false,"prevItem":{"title":"Arrow Promoted to Adopt by Technology Radar","permalink":"/community/blog/2020/10/28/arrow-promoted-to-adopt"},"nextItem":{"title":"Technology Radar Promotes Arrow to \'Adopt\'","permalink":"/community/blog/2020/10/28/technology-radar-promotes-arrow"}},"content":"Lenses are not part of the Kotlin Standard Library yet, so we will need to use an Open Source library called Arrow-kt. Arrow-kt is a huge community effort to bring some of the missing functional programming features to Kotlin."},{"id":"/2020/10/28/technology-radar-promotes-arrow","metadata":{"permalink":"/community/blog/2020/10/28/technology-radar-promotes-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-10-28-technology-radar-promotes-arrow.md","source":"@site/content/blog/2020-10-28-technology-radar-promotes-arrow.md","title":"Technology Radar Promotes Arrow to \'Adopt\'","description":"Arrow has been promoted to \u201cAdopt\u201d by ThoughtWorks\u2019 technology guide Technology Radar.","date":"2020-10-28T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Technology Radar Promotes Arrow to \'Adopt\'","image":"https://www.47deg.com/assets/img/blog/featured_images/2020-10-28-arrow-promoted-to-adopt.jpg","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/arrow-promoted-to-adopt/"},"unlisted":false,"prevItem":{"title":"How to fix the pain of modifying Kotlin nested data classes","permalink":"/community/blog/2020/10/28/modifying-kotlin-nested-data-classes"},"nextItem":{"title":"Writing Kotlin Compiler Plugins with Arrow Meta","permalink":"/community/blog/2020/10/08/writing-kotlin-compiler-plugins-talk"}},"content":"Arrow has been promoted to \u201cAdopt\u201d by ThoughtWorks\u2019 technology guide *Technology Radar*."},{"id":"/2020/10/08/writing-kotlin-compiler-plugins-talk","metadata":{"permalink":"/community/blog/2020/10/08/writing-kotlin-compiler-plugins-talk","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-10-08-writing-kotlin-compiler-plugins-talk.md","source":"@site/content/blog/2020-10-08-writing-kotlin-compiler-plugins-talk.md","title":"Writing Kotlin Compiler Plugins with Arrow Meta","description":"Lean how to write and test compiler plugins and IDE plugins with Arrow Meta.","date":"2020-10-08T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Writing Kotlin Compiler Plugins with Arrow Meta","image":"https://codingwithmohit.com/assets/images/talks/writing_kotlin_compiler_plugins_with_arrow_meta.jpg","category":"videos","tags":["meta","videos"],"link":"https://www.droidcon.com/media-detail?video=470216591","event":"Droidcon EMEA 2020"},"unlisted":false,"prevItem":{"title":"Technology Radar Promotes Arrow to \'Adopt\'","permalink":"/community/blog/2020/10/28/technology-radar-promotes-arrow"},"nextItem":{"title":"Type Proofs and FP for the Kotlin Type System","permalink":"/community/blog/2020/06/16/type-proofs-fp-kotlin-talk"}},"content":"Lean how to write and test compiler plugins and IDE plugins with Arrow Meta."},{"id":"/2020/06/16/type-proofs-fp-kotlin-talk","metadata":{"permalink":"/community/blog/2020/06/16/type-proofs-fp-kotlin-talk","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-06-16-type-proofs-fp-kotlin-talk.md","source":"@site/content/blog/2020-06-16-type-proofs-fp-kotlin-talk.md","title":"Type Proofs and FP for the Kotlin Type System","description":"Type Proofs is a new compiler plugin built on Arrow Meta enabling new features in the Kotlin type system, such as Type Classes, Union Types, Type Refinements, and many other extensions that make Functional Programming easier in Kotlin.","date":"2020-06-16T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.495,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Type Proofs and FP for the Kotlin Type System","image":"https://img.youtube.com/vi/ETn_6LmMjho/hqdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://youtu.be/ETn_6LmMjho","event":"KTUG Munich June Meetup"},"unlisted":false,"prevItem":{"title":"Writing Kotlin Compiler Plugins with Arrow Meta","permalink":"/community/blog/2020/10/08/writing-kotlin-compiler-plugins-talk"},"nextItem":{"title":"Asynchronisme et hexagone en Kotlin avec ArrowKt","permalink":"/community/blog/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow"}},"content":"Type Proofs is a new compiler plugin built on Arrow Meta enabling new features in the Kotlin type system, such as Type Classes, Union Types, Type Refinements, and many other extensions that make Functional Programming easier in Kotlin.\\n\\nType Proofs propositions are expressed as extension functions that unlock new relationships between types ad-hoc whilst remaining fully compatible with subtype polymorphism and the existing inheritance type system.\\n\\nThis talk demonstrates some of the new features the Arrow team is introducing in Arrow at the type level and IDE and how others can benefit from them when building libraries and applications."},{"id":"/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow","metadata":{"permalink":"/community/blog/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-06-11-asynchronisme-et-hexagone-en-kotlin-avec-Arrow.md","source":"@site/content/blog/2020-06-11-asynchronisme-et-hexagone-en-kotlin-avec-Arrow.md","title":"Asynchronisme et hexagone en Kotlin avec ArrowKt","description":"J\'aime bien le DDD et surtout les architectures hexagonales. Avoir un domaine auto-portant et non coupl\xe9 \xe0 des blocs techniques comme Spring (ou autres) apporte beaucoup dans la testabilit\xe9 et l\'\xe9volutivit\xe9 de l\'application.","date":"2020-06-11T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.665,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Asynchronisme et hexagone en Kotlin avec ArrowKt","image":"https://img.youtube.com/vi/moJpV-BgezM/hqdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/moJpV-BgezM","event":"Lambda Lille"},"unlisted":false,"prevItem":{"title":"Type Proofs and FP for the Kotlin Type System","permalink":"/community/blog/2020/06/16/type-proofs-fp-kotlin-talk"},"nextItem":{"title":"Arrow Fx: Functional Domain Modeling with Kotlin","permalink":"/community/blog/2020/06/05/functional-domain-modeling-kotlin"}},"content":"J\'aime bien le DDD et surtout les architectures hexagonales. Avoir un domaine auto-portant et non coupl\xe9 \xe0 des blocs techniques comme Spring (ou autres) apporte beaucoup dans la testabilit\xe9 et l\'\xe9volutivit\xe9 de l\'application.\\nLes mod\xe8les d\'asynchronismes (programmation r\xe9active, retard\xe9e, coroutines...) emp\xeachent la dissociation stricte de notre mod\xe8le m\xe9tier et de notre code infra dans un langage comme Kotlin.\\nOblig\xe9 d\'utiliser une lib de coroutine ou autre programmation reactive.\\nDeux solutions s\'offrent alors :\\n- D\xe9finir que les mod\xe8les d\'asynchronisme sont des invariants de notre domaine et accepter ce couplage\\n- Chercher comment mod\xe9liser notre domaine comme un ensemble de comportements asynchrones\\nDans ce talk nous allons voir comment r\xe9aliser la deuxi\xe8me solution en utilisant la librairie Arrow et son mod\xe8le conceptuel d\'asynchronisme pour nous permettre de d\xe9coupler notre domaine de toute logique d\'infrastructure."},{"id":"/2020/06/05/functional-domain-modeling-kotlin","metadata":{"permalink":"/community/blog/2020/06/05/functional-domain-modeling-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-06-05-functional-domain-modeling-kotlin.md","source":"@site/content/blog/2020-06-05-functional-domain-modeling-kotlin.md","title":"Arrow Fx: Functional Domain Modeling with Kotlin","description":"Arrow Fx is a purely functional concurrency framework for Kotlin\u2019s suspend system.","date":"2020-06-05T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.405,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Fx: Functional Domain Modeling with Kotlin","image":"https://img.youtube.com/vi/6sw8GAhUJz0/maxresdefault.jpg","category":"videos","tags":["fx","videos"],"link":"https://youtu.be/6sw8GAhUJz0","event":"Kotliners 2020"},"unlisted":false,"prevItem":{"title":"Asynchronisme et hexagone en Kotlin avec ArrowKt","permalink":"/community/blog/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow"},"nextItem":{"title":"Type Proofs and FP for the Kotlin Type System","permalink":"/community/blog/2020/05/27/type-proofs-fp-kotlin-talk"}},"content":"Arrow Fx is a purely functional concurrency framework for Kotlin\u2019s suspend system.\\n\\nIn this talk, we will learn how typed functional programming and functional domain modeling powered by Arrow Optics, Fx, and Meta can be applied to assemble powerful applications and architectures from small and simple building blocks.\\n\\nSimon and Raul will cover important topics and patterns such as optics, union types, refined types, type classes, automatic task cancellation, safe resource handling, and compare how Arrow Fx differs from KotlinX coroutines."},{"id":"/2020/05/27/type-proofs-fp-kotlin-talk","metadata":{"permalink":"/community/blog/2020/05/27/type-proofs-fp-kotlin-talk","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-05-27-type-proofs-fp-kotlin-talk.md","source":"@site/content/blog/2020-05-27-type-proofs-fp-kotlin-talk.md","title":"Type Proofs and FP for the Kotlin Type System","description":"Type Proofs is a new compiler plugin built on Arrow Meta enabling new features in the Kotlin type system, such as Type Classes, Union Types, Type Refinements, and many other extensions that make Functional Programming easier in Kotlin.","date":"2020-05-27T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.495,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Type Proofs and FP for the Kotlin Type System","image":"https://img.youtube.com/vi/lK80dPcsNUg/hqdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://www.youtube.com/watch?v=lK80dPcsNUg&t=353s","event":"Chicago Kotlin User Group Meetup"},"unlisted":false,"prevItem":{"title":"Arrow Fx: Functional Domain Modeling with Kotlin","permalink":"/community/blog/2020/06/05/functional-domain-modeling-kotlin"},"nextItem":{"title":"Android architectures with Arrow Fx","permalink":"/community/blog/2020/05/06/android-architectures-arrow-fx"}},"content":"Type Proofs is a new compiler plugin built on Arrow Meta enabling new features in the Kotlin type system, such as Type Classes, Union Types, Type Refinements, and many other extensions that make Functional Programming easier in Kotlin.\\n\\nType Proofs propositions are expressed as extension functions that unlock new relationships between types ad-hoc whilst remaining fully compatible with subtype polymorphism and the existing inheritance type system.\\n\\nThis talk demonstrates some of the new features the Arrow team is introducing in Arrow at the type level and IDE and how others can benefit from them when building libraries and applications."},{"id":"/2020/05/06/android-architectures-arrow-fx","metadata":{"permalink":"/community/blog/2020/05/06/android-architectures-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-05-06-android-architectures-arrow-fx.md","source":"@site/content/blog/2020-05-06-android-architectures-arrow-fx.md","title":"Android architectures with Arrow Fx","description":"May 2020 Online Kotlin Meetup","date":"2020-05-06T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.43,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Android architectures with Arrow Fx","image":"https://img.youtube.com/vi/r4D-oFd6wmY/maxresdefault.jpg","category":"videos","tags":["fx","videos"],"link":"https://youtu.be/r4D-oFd6wmY","event":"May 2020 Online Kotlin Meetup"},"unlisted":false,"prevItem":{"title":"Type Proofs and FP for the Kotlin Type System","permalink":"/community/blog/2020/05/27/type-proofs-fp-kotlin-talk"},"nextItem":{"title":"Writing a Kotlin Compiler Plugin with Arrow Meta","permalink":"/community/blog/2020/04/08/writing-compiler-plugin-with-with-arrow-meta"}},"content":"May 2020 Online Kotlin Meetup\\n\\nDaniel Montoya Ramos - Senior Software Engineer @47deg\\nAndroid Jetpack Compose\\n\\nDani will show a new way of building UI\'s in Android using Jetpack Compose, comparing Imperative vs Declarative approaches. He\'ll look at managing state changes, composing functions as well as some of the gotchas and wishes for the future.\\n\\nAlberto Ballano - Senior Software Engineer @47deg\\nAndroid architectures with Arrow Fx\\n\\nAlberto will talk about typical Android architectures, and how can they benefit from Functional Programming techniques available in Arrow."},{"id":"/2020/04/08/writing-compiler-plugin-with-with-arrow-meta","metadata":{"permalink":"/community/blog/2020/04/08/writing-compiler-plugin-with-with-arrow-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-04-08-writing-compiler-plugin-with-with-arrow-meta.md","source":"@site/content/blog/2020-04-08-writing-compiler-plugin-with-with-arrow-meta.md","title":"Writing a Kotlin Compiler Plugin with Arrow Meta","description":"Learn how to write and test the debuglog compiler plugin in Arrow Meta. Here is the compiler plugin debulog-arrow-meta explained in the article.","date":"2020-04-08T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.115,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Writing a Kotlin Compiler Plugin with Arrow Meta","image":"https://meta.arrow-kt.io/img/demos/hello-world-compiler-plugin.gif","category":"articles","tags":["meta","articles"],"link":"https://medium.com/@heyitsmohit/writing-kotlin-compiler-plugin-with-arrow-meta-cf7b3689aa3e"},"unlisted":false,"prevItem":{"title":"Android architectures with Arrow Fx","permalink":"/community/blog/2020/05/06/android-architectures-arrow-fx"},"nextItem":{"title":"Template-Oriented-Programming to Ship Faster, Part-1","permalink":"/community/blog/2020/04/06/template-oriented-programming-talk"}},"content":"Learn how to write and test the [debuglog](https://github.com/kevinmost/debuglog) compiler plugin in Arrow Meta. Here is the compiler plugin [debulog-arrow-meta](https://github.com/msya/debuglog-arrow-meta) explained in the article."},{"id":"/2020/04/06/template-oriented-programming-talk","metadata":{"permalink":"/community/blog/2020/04/06/template-oriented-programming-talk","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-04-06-template-oriented-programming-talk.md","source":"@site/content/blog/2020-04-06-template-oriented-programming-talk.md","title":"Template-Oriented-Programming to Ship Faster, Part-1","description":"Learn about the magic of Ad-hoc polymorphism using Arrow typeclasses with simple examples.","date":"2020-04-06T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.065,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Template-Oriented-Programming to Ship Faster, Part-1","image":"https://img.youtube.com/vi/_QBlKtUY6ac/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/_QBlKtUY6ac","event":"Kotlin User Group, Hyderabad, Online Meetup"},"unlisted":false,"prevItem":{"title":"Writing a Kotlin Compiler Plugin with Arrow Meta","permalink":"/community/blog/2020/04/08/writing-compiler-plugin-with-with-arrow-meta"},"nextItem":{"title":"Template-Oriented-Programming to Ship Faster","permalink":"/community/blog/2020/04/06/template-oriented-programming"}},"content":"Learn about the magic of Ad-hoc polymorphism using Arrow typeclasses with simple examples."},{"id":"/2020/04/06/template-oriented-programming","metadata":{"permalink":"/community/blog/2020/04/06/template-oriented-programming","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-04-06-template-oriented-programming.md","source":"@site/content/blog/2020-04-06-template-oriented-programming.md","title":"Template-Oriented-Programming to Ship Faster","description":"With a POC using Spring-fu + Kotlin + Arrow, let\'s Convert Monomorphic code (for common use-cases such as Auth, Validation) to Polymorphic reusable templates, to be reused among heterogeneous services built on different tech-stacks (blocking/non-blocking). This helps accelerate feature development.","date":"2020-04-06T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.2,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Template-Oriented-Programming to Ship Faster","image":"https://img.youtube.com/vi/_QBlKtUY6ac/maxresdefault.jpg","category":"articles","tags":["core","articles"],"link":"https://overfullstack.github.io/posts/top-with-ad-hoc-polymorphism/"},"unlisted":false,"prevItem":{"title":"Template-Oriented-Programming to Ship Faster, Part-1","permalink":"/community/blog/2020/04/06/template-oriented-programming-talk"},"nextItem":{"title":"Explaining the Arrow Android sample","permalink":"/community/blog/2020/04/01/explaining-arrow-android-sample"}},"content":"With a POC using Spring-fu + Kotlin + Arrow, let\'s Convert Monomorphic code (for common use-cases such as Auth, Validation) to Polymorphic reusable templates, to be reused among heterogeneous services built on different tech-stacks (blocking/non-blocking). This helps accelerate feature development."},{"id":"/2020/04/01/explaining-arrow-android-sample","metadata":{"permalink":"/community/blog/2020/04/01/explaining-arrow-android-sample","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-04-01-explaining-arrow-android-sample.md","source":"@site/content/blog/2020-04-01-explaining-arrow-android-sample.md","title":"Explaining the Arrow Android sample","description":"Arrow is an exciting development for Kotlin developers interested in functional programming and, more broadly, pushing the limits of the Kotlin compiler.","date":"2020-04-01T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Explaining the Arrow Android sample","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"articles","tags":["core","articles"],"link":"https://medium.com/default-to-open/explaining-the-arrow-android-sample-ee5c8bdfe88a"},"unlisted":false,"prevItem":{"title":"Template-Oriented-Programming to Ship Faster","permalink":"/community/blog/2020/04/06/template-oriented-programming"},"nextItem":{"title":"IO integration with kotlinx.coroutines","permalink":"/community/blog/2020/03/02/io-integration-kotlinx-coroutines"}},"content":"Arrow is an exciting development for Kotlin developers interested in functional programming and, more broadly, pushing the limits of the Kotlin compiler."},{"id":"/2020/03/02/io-integration-kotlinx-coroutines","metadata":{"permalink":"/community/blog/2020/03/02/io-integration-kotlinx-coroutines","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-03-02-io-integration-kotlinx-coroutines.md","source":"@site/content/blog/2020-03-02-io-integration-kotlinx-coroutines.md","title":"IO integration with kotlinx.coroutines","description":"This article showcases the brand new Arrow integration module for KotlinX Coroutines included in the Arrow 0.10.5 release.","date":"2020-03-02T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.09,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"IO integration with kotlinx.coroutines","image":"https://www.47deg.com/assets/img/blog/featured_images/2020-03-26-io-integration-kotlinx-coroutines.jpg","category":"articles","tags":["fx","articles"],"link":"https://www.47deg.com/blog/arrow-kotlinx-integration/"},"unlisted":false,"prevItem":{"title":"Explaining the Arrow Android sample","permalink":"/community/blog/2020/04/01/explaining-arrow-android-sample"},"nextItem":{"title":"FP with Kotlin/Arrow: Monad Comprehensions & Parallel Processing","permalink":"/community/blog/2020/02/26/fp-with-kotlin-arrow"}},"content":"This article showcases the brand new Arrow integration module for KotlinX Coroutines included in the Arrow 0.10.5 release."},{"id":"/2020/02/26/fp-with-kotlin-arrow","metadata":{"permalink":"/community/blog/2020/02/26/fp-with-kotlin-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-02-26-fp-with-kotlin-arrow.md","source":"@site/content/blog/2020-02-26-fp-with-kotlin-arrow.md","title":"FP with Kotlin/Arrow: Monad Comprehensions & Parallel Processing","description":"Arrow has multiple libraries available for functional programming. In this talk we\'ll focus on Arrow FX and learn how to handle IO in a functional way with an introduction to monadic composition. Then we\'ll examine how to compose monads in a cleaner fashion with Arrow FX\'s monad comprehensions. Finally, we\'ll take a look at how to parallelize IO monads with parallel map strategies.","date":"2020-02-26T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.315,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"FP with Kotlin/Arrow: Monad Comprehensions & Parallel Processing","image":"https://img.youtube.com/vi/nAtzuIRryuE/maxresdefault.jpg","category":"videos","tags":["fx","videos"],"link":"https://youtu.be/nAtzuIRryuE"},"unlisted":false,"prevItem":{"title":"IO integration with kotlinx.coroutines","permalink":"/community/blog/2020/03/02/io-integration-kotlinx-coroutines"},"nextItem":{"title":"What could possibly go wrong? - A safer programming with Arrow","permalink":"/community/blog/2020/02/26/safer-programming-with-arrow"}},"content":"Arrow has multiple libraries available for functional programming. In this talk we\'ll focus on Arrow FX and learn how to handle IO in a functional way with an introduction to monadic composition. Then we\'ll examine how to compose monads in a cleaner fashion with Arrow FX\'s monad comprehensions. Finally, we\'ll take a look at how to parallelize IO monads with parallel map strategies."},{"id":"/2020/02/26/safer-programming-with-arrow","metadata":{"permalink":"/community/blog/2020/02/26/safer-programming-with-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-02-26-safer-programming-with-arrow.md","source":"@site/content/blog/2020-02-26-safer-programming-with-arrow.md","title":"What could possibly go wrong? - A safer programming with Arrow","description":"Your Kotlin app grabs data from an API, transforms it and saves the processed data in a database. However, there are so many things that could go wrong at runtime treat your impure functions as computations with context, pass them around just like other values, and make the necessary unsafe invocation from a single point of your app, your main function.","date":"2020-02-26T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.785,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"What could possibly go wrong? - A safer programming with Arrow","image":"https://img.youtube.com/vi/C9SmleSSeGk/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://youtu.be/C9SmleSSeGk"},"unlisted":false,"prevItem":{"title":"FP with Kotlin/Arrow: Monad Comprehensions & Parallel Processing","permalink":"/community/blog/2020/02/26/fp-with-kotlin-arrow"},"nextItem":{"title":"Kotlin Functional Programming: Cleaner Composition with Monad Comprehensions in Arrow Fx","permalink":"/community/blog/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx"}},"content":"Your Kotlin app grabs data from an API, transforms it and saves the processed data in a database. However, there are so many things that could go wrong at runtime: the API might be inaccessible, the data is not what you expected or the data can\'t be persisted in the database. You can start adding try catch blocks to your function in your objects, but there is a better way to do it: treat your impure functions as computations with context, pass them around just like other values, and make the necessary unsafe invocation from a single point of your app, your main function.\\n\\nThis talk will walk you through the core functional concepts of Arrow, you will learn how Some, Either and even IO are functor, applicative and monad. You can use the code example from this talk as a starting point for your Arrow-learning, to write safer, simpler and more elegant functional code in Kotlin."},{"id":"/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx","metadata":{"permalink":"/community/blog/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-01-29-cleaner-composition-with-monad-comprehensions-arrow-fx.md","source":"@site/content/blog/2020-01-29-cleaner-composition-with-monad-comprehensions-arrow-fx.md","title":"Kotlin Functional Programming: Cleaner Composition with Monad Comprehensions in Arrow Fx","description":"Learn how to write cleaner monadic composition in Kotlin with Arrow\u2019s monad comprehensions, available in Arrow FX.","date":"2020-01-29T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.085,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin Functional Programming: Cleaner Composition with Monad Comprehensions in Arrow Fx","image":"https://raw.githubusercontent.com/arrow-kt/arrow-site/master/docs/img/fx/arrow-fx-brand-sidebar.svg?sanitize=true","category":"articles","tags":["fx","articles"],"link":"https://lambda.show/blog/arrow-io-monad-comprehensions-cleaner-monadic-composition"},"unlisted":false,"prevItem":{"title":"What could possibly go wrong? - A safer programming with Arrow","permalink":"/community/blog/2020/02/26/safer-programming-with-arrow"},"nextItem":{"title":"Kotlin Functional Programming: Monads & Composition with Arrow Fx","permalink":"/community/blog/2020/01/29/monads-and-composition-with-arrow-fx"}},"content":"Learn how to write cleaner monadic composition in Kotlin with Arrow\u2019s monad comprehensions, available in Arrow FX."},{"id":"/2020/01/29/monads-and-composition-with-arrow-fx","metadata":{"permalink":"/community/blog/2020/01/29/monads-and-composition-with-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-01-29-monads-and-composition-with-arrow-fx.md","source":"@site/content/blog/2020-01-29-monads-and-composition-with-arrow-fx.md","title":"Kotlin Functional Programming: Monads & Composition with Arrow Fx","description":"Arrow is a library created by folks over at a company called 47 degrees . In a nutshell, Arrow brings a slew of functional programming features to Kotlin. It is heavily inspired by Scala and Haskell, and emphasizes a lot of the concepts that those languages started","date":"2020-01-29T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.235,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin Functional Programming: Monads & Composition with Arrow Fx","image":"https://raw.githubusercontent.com/arrow-kt/arrow-site/master/docs/img/fx/arrow-fx-brand-sidebar.svg?sanitize=true","category":"articles","tags":["fx","articles"],"link":"https://lambda.show/blog/arrow-io-monad"},"unlisted":false,"prevItem":{"title":"Kotlin Functional Programming: Cleaner Composition with Monad Comprehensions in Arrow Fx","permalink":"/community/blog/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx"},"nextItem":{"title":"Kotlin Functional Programming: Parallel Processing The Functional Way with Arrow Fx","permalink":"/community/blog/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx"}},"content":"Arrow is a library created by folks over at a company called 47 degrees . In a nutshell, Arrow brings a slew of functional programming features to Kotlin. It is heavily inspired by Scala and Haskell, and emphasizes a lot of the concepts that those languages started"},{"id":"/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx","metadata":{"permalink":"/community/blog/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-01-29-parallel-processing-the-functional-way-with-arrow-fx.md","source":"@site/content/blog/2020-01-29-parallel-processing-the-functional-way-with-arrow-fx.md","title":"Kotlin Functional Programming: Parallel Processing The Functional Way with Arrow Fx","description":"Learn how to handle parallel processing in Kotlin with Arrow IO monads.","date":"2020-01-29T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin Functional Programming: Parallel Processing The Functional Way with Arrow Fx","image":"https://raw.githubusercontent.com/arrow-kt/arrow-site/master/docs/img/fx/arrow-fx-brand-sidebar.svg?sanitize=true","category":"articles","tags":["fx","articles"],"link":"https://lambda.show/blog/arrow-io-parallel"},"unlisted":false,"prevItem":{"title":"Kotlin Functional Programming: Monads & Composition with Arrow Fx","permalink":"/community/blog/2020/01/29/monads-and-composition-with-arrow-fx"},"nextItem":{"title":"Arrow Comonad Approach for GameOfLife with Android Compose","permalink":"/community/blog/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife"}},"content":"Learn how to handle parallel processing in Kotlin with Arrow IO monads."},{"id":"/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife","metadata":{"permalink":"/community/blog/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2020-01-14-Arrow-Comonad-Android-Compose-gameOfLife.md","source":"@site/content/blog/2020-01-14-Arrow-Comonad-Android-Compose-gameOfLife.md","title":"Arrow Comonad Approach for GameOfLife with Android Compose","description":"The purpose of this article is complement the bow + SwifUi solution for the game of live we can find here https://www.47deg.com/blog/conway-swift/ with the arrow + compose version.","date":"2020-01-14T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.14,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Comonad Approach for GameOfLife with Android Compose","image":"https://user-images.githubusercontent.com/39838885/72436632-a95c6380-377f-11ea-8a31-fe0c05d49946.gif","category":"articles","tags":["fx","articles"],"link":"https://github.com/matiaslev/ArrowComposeLifeGame/tree/master"},"unlisted":false,"prevItem":{"title":"Kotlin Functional Programming: Parallel Processing The Functional Way with Arrow Fx","permalink":"/community/blog/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx"},"nextItem":{"title":"Kotlin coroutines with arrow-fx","permalink":"/community/blog/2019/12/15/Kotlin-coroutines-with-arrow-fx"}},"content":"The purpose of this article is complement the bow + SwifUi solution for the game of live we can find here https://www.47deg.com/blog/conway-swift/ with the arrow + compose version."},{"id":"/2019/12/15/Kotlin-coroutines-with-arrow-fx","metadata":{"permalink":"/community/blog/2019/12/15/Kotlin-coroutines-with-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-12-15-Kotlin-coroutines-with-arrow-fx.md","source":"@site/content/blog/2019-12-15-Kotlin-coroutines-with-arrow-fx.md","title":"Kotlin coroutines with arrow-fx","description":"The purpose of this article is to summarize the approaches from questions at Slack about the usage of Either, Option and other datatypes and to give a tour of arrow-fx usage and APIs.","date":"2019-12-15T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.165,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin coroutines with arrow-fx","image":"https://www.pacoworks.com/content/images/2016/05/banner_v2.png","category":"articles","tags":["fx","articles"],"link":"https://www.pacoworks.com/2019/12/15/kotlin-coroutines-with-arrow-fx/"},"unlisted":false,"prevItem":{"title":"Arrow Comonad Approach for GameOfLife with Android Compose","permalink":"/community/blog/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife"},"nextItem":{"title":"Conway\'s Game of Life using Kotlin and Arrow","permalink":"/community/blog/2019/12/12/GOL-using-Kotlin-and-Arrow"}},"content":"The purpose of this article is to summarize the approaches from questions at Slack about the usage of Either, Option and other datatypes and to give a tour of arrow-fx usage and APIs."},{"id":"/2019/12/12/GOL-using-Kotlin-and-Arrow","metadata":{"permalink":"/community/blog/2019/12/12/GOL-using-Kotlin-and-Arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-12-12-GOL-using-Kotlin-and-Arrow.md","source":"@site/content/blog/2019-12-12-GOL-using-Kotlin-and-Arrow.md","title":"Conway\'s Game of Life using Kotlin and Arrow","description":"An article of a series on Functional Programming solutions for the Global Day of Coderetreat challenge. In this case, it shows an approach for it using Kotlin and Functional Programming provided by the Arrow library.","date":"2019-12-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Conway\'s Game of Life using Kotlin and Arrow","image":"https://www.47deg.com/assets/img/blog/featured_images/2019-12-12-game-of-life-kotlin.jpg","category":"articles","tags":["core","fx","articles"],"link":"https://www.47deg.com/blog/conway-kotlin/"},"unlisted":false,"prevItem":{"title":"Kotlin coroutines with arrow-fx","permalink":"/community/blog/2019/12/15/Kotlin-coroutines-with-arrow-fx"},"nextItem":{"title":"Keep insisting - Arrow Meta","permalink":"/community/blog/2019/12/06/kotlinconf-arrow-meta"}},"content":"An article of a series on Functional Programming solutions for the Global Day of Coderetreat challenge. In this case, it shows an approach for it using Kotlin and Functional Programming provided by the Arrow library."},{"id":"/2019/12/06/kotlinconf-arrow-meta","metadata":{"permalink":"/community/blog/2019/12/06/kotlinconf-arrow-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-12-06-kotlinconf-arrow-meta.md","source":"@site/content/blog/2019-12-06-kotlinconf-arrow-meta.md","title":"Keep insisting - Arrow Meta","description":"Arrow Meta is a library that empowers library and application authors with the ability to write plugins for the Kotlin compiler. Compiler plugins have access to all compiler phases and can intercept and modify the AST, descriptors, and IR intermediate lang for bytecode generation.","date":"2019-12-06T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.22,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Keep insisting - Arrow Meta","image":"https://img.youtube.com/vi/n9smQNxUyBI/maxresdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://youtu.be/n9smQNxUyBI","event":"KotlinConf, Copenhagen"},"unlisted":false,"prevItem":{"title":"Conway\'s Game of Life using Kotlin and Arrow","permalink":"/community/blog/2019/12/12/GOL-using-Kotlin-and-Arrow"},"nextItem":{"title":"Arrow Fx & Arrow Meta - Functional Programming for the masses","permalink":"/community/blog/2019/11/27/functional-jvm-arrow-fx-meta"}},"content":"Arrow Meta is a library that empowers library and application authors with the ability to write plugins for the Kotlin compiler. Compiler plugins have access to all compiler phases and can intercept and modify the AST, descriptors, and IR intermediate lang for bytecode generation."},{"id":"/2019/11/27/functional-jvm-arrow-fx-meta","metadata":{"permalink":"/community/blog/2019/11/27/functional-jvm-arrow-fx-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-11-27-functional-jvm-arrow-fx-meta.md","source":"@site/content/blog/2019-11-27-functional-jvm-arrow-fx-meta.md","title":"Arrow Fx & Arrow Meta - Functional Programming for the masses","description":"In this meetup we discuss the new features of Arrow Fx to write \u201ceffectful\u201d programs with an emphasis on simple and declarative programming for everyone.","date":"2019-11-27T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.235,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Fx & Arrow Meta - Functional Programming for the masses","image":"https://img.youtube.com/vi/DaognWtZCbs/maxresdefault.jpg","category":"videos","tags":["meta","fx","videos"],"link":"https://www.youtube.com/watch?v=DaognWtZCbs","event":"Functional JVM Meetup, Prague"},"unlisted":false,"prevItem":{"title":"Keep insisting - Arrow Meta","permalink":"/community/blog/2019/12/06/kotlinconf-arrow-meta"},"nextItem":{"title":"Arrow Meta - Enabling Functional Programming in the Kotlin Compiler","permalink":"/community/blog/2019/10/18/lambda-world-arrow-meta"}},"content":"In this meetup we discuss the new features of Arrow Fx to write \u201ceffectful\u201d programs with an emphasis on simple and declarative programming for everyone.\\nAdditionally, we see how Arrow Meta works and how we can use it to improve the ergonomics of Functional Programming in Kotlin."},{"id":"/2019/10/18/lambda-world-arrow-meta","metadata":{"permalink":"/community/blog/2019/10/18/lambda-world-arrow-meta","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-10-18-lambda-world-arrow-meta.md","source":"@site/content/blog/2019-10-18-lambda-world-arrow-meta.md","title":"Arrow Meta - Enabling Functional Programming in the Kotlin Compiler","description":"Arrow Meta is a library that empowers library and application authors with the ability to write plugins for the Kotlin compiler. Compiler plugins have access to all compiler phases and can intercept and modify the AST, descriptors, and IR intermediate lang for bytecode generation.","date":"2019-10-18T00:00:00.000Z","tags":[{"label":"meta","permalink":"/community/blog/tags/meta"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.22,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow Meta - Enabling Functional Programming in the Kotlin Compiler","image":"https://img.youtube.com/vi/WKR384ZeBgk/maxresdefault.jpg","category":"videos","tags":["meta","videos"],"link":"https://www.youtube.com/watch?v=WKR384ZeBgk","event":"Lambda World, C\xe1diz, Spain"},"unlisted":false,"prevItem":{"title":"Arrow Fx & Arrow Meta - Functional Programming for the masses","permalink":"/community/blog/2019/11/27/functional-jvm-arrow-fx-meta"},"nextItem":{"title":"Kotlin and Arrow: the functional way","permalink":"/community/blog/2019/08/08/kotlin-and-arrow-the-functional-way"}},"content":"Arrow Meta is a library that empowers library and application authors with the ability to write plugins for the Kotlin compiler. Compiler plugins have access to all compiler phases and can intercept and modify the AST, descriptors, and IR intermediate lang for bytecode generation."},{"id":"/2019/08/08/kotlin-and-arrow-the-functional-way","metadata":{"permalink":"/community/blog/2019/08/08/kotlin-and-arrow-the-functional-way","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-08-08-kotlin-and-arrow-the-functional-way.md","source":"@site/content/blog/2019-08-08-kotlin-and-arrow-the-functional-way.md","title":"Kotlin and Arrow: the functional way","description":"Kotlin is a great language for developing server-side applications; it\'s an object-oriented language and also a functional one, supporting features such as function types, lambdas or higher order functions. But...is this enough to switch completely from an imperative paradigm to a functional paradigm?","date":"2019-08-08T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.33,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin and Arrow: the functional way","image":"https://pbs.twimg.com/media/D8xN-4jWkAAceCW.jpg","category":"videos","tags":["core","videos"],"link":"https://thoughtworks.wistia.com/medias/ifra1gzrho","event":"xConf, Barcelona, Spain"},"unlisted":false,"prevItem":{"title":"Arrow Meta - Enabling Functional Programming in the Kotlin Compiler","permalink":"/community/blog/2019/10/18/lambda-world-arrow-meta"},"nextItem":{"title":"Effect polymorphism with Arrow FX","permalink":"/community/blog/2019/07/22/polymorphic-fx"}},"content":"Kotlin is a great language for developing server-side applications; it\'s an object-oriented language and also a functional one, supporting features such as function types, lambdas or higher order functions. But...is this enough to switch completely from an imperative paradigm to a functional paradigm?\\n\\nIn this talk by Noe Luaces, we\'ll see how features from Arrow library completes Kotlin in order to follow a pure functional way."},{"id":"/2019/07/22/polymorphic-fx","metadata":{"permalink":"/community/blog/2019/07/22/polymorphic-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-07-22-polymorphic-fx.md","source":"@site/content/blog/2019-07-22-polymorphic-fx.md","title":"Effect polymorphism with Arrow FX","description":"Wonder how to handle side effects in a very clean way while abstracting the real effect implementation? #Arrow #FX provides an easy way to do this, without the burden of Higher-Kinded Types.","date":"2019-07-22T00:00:00.000Z","tags":[{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.16,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Effect polymorphism with Arrow FX","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"articles","tags":["fx","articles"],"link":"https://www.msec.it/blog/effect-polymorphism-with-arrow-fx/"},"unlisted":false,"prevItem":{"title":"Kotlin and Arrow: the functional way","permalink":"/community/blog/2019/08/08/kotlin-and-arrow-the-functional-way"},"nextItem":{"title":"Self-contained example of testing with modules and Arrow FX","permalink":"/community/blog/2019/07/05/testing-with-modules"}},"content":"Wonder how to handle side effects in a very clean way while abstracting the real effect implementation? #Arrow #FX provides an easy way to do this, without the burden of Higher-Kinded Types."},{"id":"/2019/07/05/testing-with-modules","metadata":{"permalink":"/community/blog/2019/07/05/testing-with-modules","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-07-05-testing-with-modules.md","source":"@site/content/blog/2019-07-05-testing-with-modules.md","title":"Self-contained example of testing with modules and Arrow FX","description":"This post shows a porting with Kotlin and Arrow FX of a self-contained testing example with Scala ZIO","date":"2019-07-05T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.09,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Self-contained example of testing with modules and Arrow FX","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"articles","tags":["core","fx","articles"],"link":"https://www.msec.it/blog/self-contained-example-of-testing-with-modules-and-arrow-fx/"},"unlisted":false,"prevItem":{"title":"Effect polymorphism with Arrow FX","permalink":"/community/blog/2019/07/22/polymorphic-fx"},"nextItem":{"title":"Modular functional programming with Kotlin","permalink":"/community/blog/2019/07/02/modular-app-kotlin"}},"content":"This post shows a porting with Kotlin and Arrow FX of a self-contained testing example with Scala ZIO"},{"id":"/2019/07/02/modular-app-kotlin","metadata":{"permalink":"/community/blog/2019/07/02/modular-app-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-07-02-modular-app-kotlin.md","source":"@site/content/blog/2019-07-02-modular-app-kotlin.md","title":"Modular functional programming with Kotlin","description":"This post proposes a possible solution in order to structure and compose a pure functional Kotlin application, in order to better manage and decouple modules, get simpler tests and manage the Dependency Injection at compile time.","date":"2019-07-02T00:00:00.000Z","tags":[],"readingTime":0.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Modular functional programming with Kotlin","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"articles","tag":["core","articles"],"link":"https://www.msec.it/blog/modular-functional-programming-composition-with-kotlin/"},"unlisted":false,"prevItem":{"title":"Self-contained example of testing with modules and Arrow FX","permalink":"/community/blog/2019/07/05/testing-with-modules"},"nextItem":{"title":"ArrowFx: Functional Programming for the masses","permalink":"/community/blog/2019/06/07/kotliners-arrow-fx"}},"content":"This post proposes a possible solution in order to structure and compose a pure functional Kotlin application, in order to better manage and decouple modules, get simpler tests and manage the Dependency Injection at compile time."},{"id":"/2019/06/07/kotliners-arrow-fx","metadata":{"permalink":"/community/blog/2019/06/07/kotliners-arrow-fx","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-06-07-kotliners-arrow-fx.md","source":"@site/content/blog/2019-06-07-kotliners-arrow-fx.md","title":"ArrowFx: Functional Programming for the masses","description":"In this talk we recap about the imminent future of Functional Programming in Kotlin. With ArrowFx you are able to encode \u201ceffectful\u201d programs in a controlled way following the FP principles through a direct syntax. You\u2019ll think you\u2019re writing imperative code!","date":"2019-06-07T00:00:00.000Z","tags":[],"readingTime":0.205,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"ArrowFx: Functional Programming for the masses","image":"https://img.youtube.com/vi/uyqqoooKpmI/maxresdefault.jpg","category":"videos","tag":["fx","videos"],"link":"https://www.youtube.com/watch?v=uyqqoooKpmI","event":"Kotliners, Budapest"},"unlisted":false,"prevItem":{"title":"Modular functional programming with Kotlin","permalink":"/community/blog/2019/07/02/modular-app-kotlin"},"nextItem":{"title":"How KEEP-87 & Typeclasses will change the way we write Kotlin","permalink":"/community/blog/2019/06/04/keep-87-and-typeclasses"}},"content":"In this talk we recap about the imminent future of Functional Programming in Kotlin. With ArrowFx you are able to encode \u201ceffectful\u201d programs in a controlled way following the FP principles through a direct syntax. You\u2019ll think you\u2019re writing imperative code!"},{"id":"/2019/06/04/keep-87-and-typeclasses","metadata":{"permalink":"/community/blog/2019/06/04/keep-87-and-typeclasses","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-06-04-keep-87-and-typeclasses.md","source":"@site/content/blog/2019-06-04-keep-87-and-typeclasses.md","title":"How KEEP-87 & Typeclasses will change the way we write Kotlin","description":"Short introduction into the proposal KEEP-87 and how it would be able to improve the language.","date":"2019-06-04T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.08,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"How KEEP-87 & Typeclasses will change the way we write Kotlin","image":"https://quickbirdstudios.com/blog/wp-content/uploads/2019/05/xFirebird.jpg.pagespeed.ic.e0DeqxTqSE.webp","category":"articles","tags":["core","articles"],"link":"https://quickbirdstudios.com/blog/keep-87-typeclasses-kotlin/"},"unlisted":false,"prevItem":{"title":"ArrowFx: Functional Programming for the masses","permalink":"/community/blog/2019/06/07/kotliners-arrow-fx"},"nextItem":{"title":"Introducing Arrow Playground","permalink":"/community/blog/2019/04/11/introducing-arrow-playground"}},"content":"Short introduction into the proposal [KEEP-87](https://github.com/Kotlin/KEEP/pull/87) and how it would be able to improve the language."},{"id":"/2019/04/11/introducing-arrow-playground","metadata":{"permalink":"/community/blog/2019/04/11/introducing-arrow-playground","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-04-11-introducing-arrow-playground.md","source":"@site/content/blog/2019-04-11-introducing-arrow-playground.md","title":"Introducing Arrow Playground","description":"Arrow Playground is a JavaScript library that creates Kotlin-aware, including Arrow, editors capable of running code from HTML block elements. This is a fork of the original Kotlin Playground work done by the JetBrains team.","date":"2019-04-11T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Introducing Arrow Playground","image":"https://www.47deg.com/assets/img/blog/featured_images/2019-04-11-introducing-arrow-playground.png","category":"articles","tags":["core","articles"],"link":"https://www.47deg.com/blog/arrow-playground/"},"unlisted":false,"prevItem":{"title":"How KEEP-87 & Typeclasses will change the way we write Kotlin","permalink":"/community/blog/2019/06/04/keep-87-and-typeclasses"},"nextItem":{"title":"Immutable Conversations - Past and Future of Arrow","permalink":"/community/blog/2019/03/12/immutable-conv-1"}},"content":"Arrow Playground is a JavaScript library that creates Kotlin-aware, including Arrow, editors capable of running code from HTML block elements. This is a fork of the original Kotlin Playground work done by the JetBrains team."},{"id":"/2019/03/12/immutable-conv-1","metadata":{"permalink":"/community/blog/2019/03/12/immutable-conv-1","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-03-12-immutable-conv-1.md","source":"@site/content/blog/2019-03-12-immutable-conv-1.md","title":"Immutable Conversations - Past and Future of Arrow","description":"In this episode, we capture a conversation between Arrow maintainers Ra\xfal Raja and Paco Estevez as they discuss the past and future of the library which is designed to bring Functional Programming to Kotlin.","date":"2019-03-12T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.17,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Immutable Conversations - Past and Future of Arrow","image":"https://img.youtube.com/vi/YtchNDjQuTU/maxresdefault.jpg","category":"videos","tags":["core","fx","videos"],"link":"https://www.youtube.com/watch?v=YtchNDjQuTU"},"unlisted":false,"prevItem":{"title":"Introducing Arrow Playground","permalink":"/community/blog/2019/04/11/introducing-arrow-playground"},"nextItem":{"title":"From Imperative to Functional Programming using Arrow","permalink":"/community/blog/2019/02/10/imperative-functional-programming-arrow"}},"content":"In this episode, we capture a conversation between Arrow maintainers Ra\xfal Raja and Paco Estevez as they discuss the past and future of the library which is designed to bring Functional Programming to Kotlin."},{"id":"/2019/02/10/imperative-functional-programming-arrow","metadata":{"permalink":"/community/blog/2019/02/10/imperative-functional-programming-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-02-10-imperative-functional-programming-arrow.md","source":"@site/content/blog/2019-02-10-imperative-functional-programming-arrow.md","title":"From Imperative to Functional Programming using Arrow","description":"As its name implies, From Imperative to Functional Programming using Arrow is a tale about migrating a simple Kotlin application written in imperative style to a fully function application with the help of the Arrow library.","date":"2019-02-10T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"tutorials","permalink":"/community/blog/tags/tutorials"}],"readingTime":0.18,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"From Imperative to Functional Programming using Arrow","image":"https://blog.frankel.ch/assets/resources/imperative-functional-programming/arrow-brand.svg","category":"tutorials","tags":["core","fx","tutorials"],"link":"https://blog.frankel.ch/imperative-functional-programming/1/"},"unlisted":false,"prevItem":{"title":"Immutable Conversations - Past and Future of Arrow","permalink":"/community/blog/2019/03/12/immutable-conv-1"},"nextItem":{"title":"Webflux with Kotlin and Arrow","permalink":"/community/blog/2019/02/03/arrow-webflux"}},"content":"As its name implies, [From Imperative to Functional Programming using Arrow](https://blog.frankel.ch/imperative-functional-programming/1/) is a tale about migrating a simple Kotlin application written in imperative style to a fully function application with the help of the Arrow library."},{"id":"/2019/02/03/arrow-webflux","metadata":{"permalink":"/community/blog/2019/02/03/arrow-webflux","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-02-03-arrow-webflux.md","source":"@site/content/blog/2019-02-03-arrow-webflux.md","title":"Webflux with Kotlin and Arrow","description":"Webflux with Kotlin and Arrow shows how you can use Arrow together with Spring Webflux to create a reactive REST application. This article explains how to use the MonoK and the FluxK Arrow extensions together with the binding function to make working with the Mono and Flux reactor constructs much easier and better understandable.","date":"2019-02-03T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.27,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Webflux with Kotlin and Arrow","image":"/img/blog-image-header.png","category":"articles","tags":["core","fx","articles"],"link":"http://www.smartjava.org/content/webflux-arrow/"},"unlisted":false,"prevItem":{"title":"From Imperative to Functional Programming using Arrow","permalink":"/community/blog/2019/02/10/imperative-functional-programming-arrow"},"nextItem":{"title":"Getting started with FP in Kotlin and Arrow: Typeclasses","permalink":"/community/blog/2019/01/03/getting-started"}},"content":"[Webflux with Kotlin and Arrow](http://www.smartjava.org/content/webflux-arrow/) shows how you can use Arrow together with Spring Webflux to create a reactive REST application. This article explains how to use the `MonoK` and the `FluxK` Arrow extensions together with the `binding` function to make working with the `Mono` and `Flux` reactor constructs much easier and better understandable."},{"id":"/2019/01/03/getting-started","metadata":{"permalink":"/community/blog/2019/01/03/getting-started","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2019-01-03-getting-started.md","source":"@site/content/blog/2019-01-03-getting-started.md","title":"Getting started with FP in Kotlin and Arrow: Typeclasses","description":"Getting started with FP in Kotlin and Arrow: Typeclasses explores part of the Arrow library by explaining how you can use Arrow to create your own typeclasses and use the ones provided by Arrow to make your code more concise and better readable.","date":"2019-01-03T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.215,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Getting started with FP in Kotlin and Arrow: Typeclasses","image":"/img/blog-image-header.png","category":"articles","tags":["core","fx","articles"],"link":"http://www.smartjava.org/content/kotlin-arrow-typeclasses/"},"unlisted":false,"prevItem":{"title":"Webflux with Kotlin and Arrow","permalink":"/community/blog/2019/02/03/arrow-webflux"},"nextItem":{"title":"Functional Hangman Game written with Arrow","permalink":"/community/blog/2018/11/30/hangman"}},"content":"[Getting started with FP in Kotlin and Arrow: Typeclasses](http://www.smartjava.org/content/kotlin-arrow-typeclasses/) explores part of the Arrow library by explaining how you can use Arrow to create your own typeclasses and use the ones provided by Arrow to make your code more concise and better readable."},{"id":"/2018/11/30/hangman","metadata":{"permalink":"/community/blog/2018/11/30/hangman","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-11-30-hangman.md","source":"@site/content/blog/2018-11-30-hangman.md","title":"Functional Hangman Game written with Arrow","description":"Functional Hangman game - console application written with Arrow. Uses the IO monad to push side effects to the edge of the system.","date":"2018-11-30T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.115,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Hangman Game written with Arrow","image":"/img/blog-image-header.png","category":"articles","tags":["core","fx","articles"],"link":"https://lordraydenmk.github.io/2018/functional-hangman-in-kotlin-with-arrow/"},"unlisted":false,"prevItem":{"title":"Getting started with FP in Kotlin and Arrow: Typeclasses","permalink":"/community/blog/2019/01/03/getting-started"},"nextItem":{"title":"Manual documentation is dead. Long live automated documentation! Automated documentation with ANK","permalink":"/community/blog/2018/11/24/ank"}},"content":"[Functional Hangman](https://lordraydenmk.github.io/2018/functional-hangman-in-kotlin-with-arrow/) game - console application written with Arrow. Uses the `IO
` monad to push side effects to the edge of the system."},{"id":"/2018/11/24/ank","metadata":{"permalink":"/community/blog/2018/11/24/ank","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-11-24-ank.md","source":"@site/content/blog/2018-11-24-ank.md","title":"Manual documentation is dead. Long live automated documentation! Automated documentation with ANK","description":"It includes how the ANK plugin works: from having a tool that evaluates and verifies your doc snippets at compile time, to generating code documentation that is always correct and up to date.","date":"2018-11-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"incubator","permalink":"/community/blog/tags/incubator"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.165,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Manual documentation is dead. Long live automated documentation! Automated documentation with ANK","image":"https://img.youtube.com/vi/kr8iWE4Jfhc/maxresdefault.jpg","category":"videos","tags":["core","incubator","videos"],"link":"https://www.youtube.com/watch?v=kr8iWE4Jfhc","event":"droidconSF, San Francisco"},"unlisted":false,"prevItem":{"title":"Functional Hangman Game written with Arrow","permalink":"/community/blog/2018/11/30/hangman"},"nextItem":{"title":"Simple Dependency Management in Kotlin","permalink":"/community/blog/2018/11/07/simple-management-dependency"}},"content":"It includes how the ANK plugin works: from having a tool that evaluates and verifies your doc snippets at compile time, to generating code documentation that is always correct and up to date."},{"id":"/2018/11/07/simple-management-dependency","metadata":{"permalink":"/community/blog/2018/11/07/simple-management-dependency","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-11-07-simple-management-dependency.md","source":"@site/content/blog/2018-11-07-simple-management-dependency.md","title":"Simple Dependency Management in Kotlin","description":"In this talk we introduce the concepts of Dependency Management as a language feature, typeclasses, and a live demo of KEEP-87. You can follow along the example in this folder.","date":"2018-11-07T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.15,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Simple Dependency Management in Kotlin","image":"https://img.youtube.com/vi/CR5h2Wq1yPE/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=CR5h2Wq1yPE","event":"AndroidTO, Toronto"},"unlisted":false,"prevItem":{"title":"Manual documentation is dead. Long live automated documentation! Automated documentation with ANK","permalink":"/community/blog/2018/11/24/ank"},"nextItem":{"title":"Polyjokes\u200a - \u200aA polymorphic approach using Arrow","permalink":"/community/blog/2018/10/21/polyjokes"}},"content":"In this talk we introduce the concepts of Dependency Management as a language feature, typeclasses, and a live demo of [KEEP-87](https://github.com/Kotlin/KEEP/pull/87). You can follow along the example in [this folder](https://github.com/arrow-kt/arrow/tree/master/modules/docs/arrow-examples/src/test/kotlin/arrow/typeclasses)."},{"id":"/2018/10/21/polyjokes","metadata":{"permalink":"/community/blog/2018/10/21/polyjokes","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-10-21-polyjokes.md","source":"@site/content/blog/2018-10-21-polyjokes.md","title":"Polyjokes\u200a - \u200aA polymorphic approach using Arrow","description":"@dcampogiani is using a polymorphic approach to retrieve a random user and then a joke about him.","date":"2018-10-21T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.11,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Polyjokes\u200a - \u200aA polymorphic approach using Arrow","image":"/img/blog-image-header.png","category":"articles","tags":["core","articles"],"link":"https://github.com/dcampogiani/polyjokes"},"unlisted":false,"prevItem":{"title":"Simple Dependency Management in Kotlin","permalink":"/community/blog/2018/11/07/simple-management-dependency"},"nextItem":{"title":"Architecting Typed FP Applications & Libraries in Kotlin with Arrow","permalink":"/community/blog/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow"}},"content":"[@dcampogiani](https://github.com/dcampogiani) is using a polymorphic approach to retrieve a random user and then a joke about him.\\n\\n[Polyjokes\u200a\u2014\u200aA polymorphic approach using Arrow](https://github.com/dcampogiani/polyjokes)"},{"id":"/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow","metadata":{"permalink":"/community/blog/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-10-05-kotlin-conf-fp-in-kotlin-with-arrow.md","source":"@site/content/blog/2018-10-05-kotlin-conf-fp-in-kotlin-with-arrow.md","title":"Architecting Typed FP Applications & Libraries in Kotlin with Arrow","description":"This talk includes a comprehensive walkthrough of the most important patterns covered by the data types and type classes we find in Arrow. Each pattern will be accompanied by code examples that illustrate how Arrow brings Typed Functional Programming to Kotlin.","date":"2018-10-05T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.22,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Architecting Typed FP Applications & Libraries in Kotlin with Arrow","image":"https://img.youtube.com/vi/VOZZTSuDMFE/maxresdefault.jpg","category":"videos","tags":["core","fx","videos"],"link":"https://www.youtube.com/watch?v=VOZZTSuDMFE","event":"KotlinConf, Amsterdam"},"unlisted":false,"prevItem":{"title":"Polyjokes\u200a - \u200aA polymorphic approach using Arrow","permalink":"/community/blog/2018/10/21/polyjokes"},"nextItem":{"title":"Arrow and Functional Programming for Kotlin Developers","permalink":"/community/blog/2018/07/24/arrow-fp-kotlin"}},"content":"This talk includes a comprehensive walkthrough of the most important patterns covered by the data types and type classes we find in Arrow. Each pattern will be accompanied by code examples that illustrate how Arrow brings Typed Functional Programming to Kotlin.\\n\\n[Sources and slides](https://github.com/47deg/arrow-architecture)"},{"id":"/2018/07/24/arrow-fp-kotlin","metadata":{"permalink":"/community/blog/2018/07/24/arrow-fp-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-07-24-arrow-fp-kotlin.md","source":"@site/content/blog/2018-07-24-arrow-fp-kotlin.md","title":"Arrow and Functional Programming for Kotlin Developers","description":"A beginner level introduction to Functional Programming for Kotlin and/or Android Developers or developers with OOP background.","date":"2018-07-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.085,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow and Functional Programming for Kotlin Developers","image":"https://img.youtube.com/vi/qYgilPqMOp0/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=qYgilPqMOp0","event":"DroidJam India, Bangalore, India"},"unlisted":false,"prevItem":{"title":"Architecting Typed FP Applications & Libraries in Kotlin with Arrow","permalink":"/community/blog/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow"},"nextItem":{"title":"Functional Programming in Kotlin with Arrow by Emmanuel Nhan","permalink":"/community/blog/2018/06/27/fp-kotlin-arrow"}},"content":"A beginner level introduction to Functional Programming for Kotlin and/or Android Developers or developers with OOP background."},{"id":"/2018/06/27/fp-kotlin-arrow","metadata":{"permalink":"/community/blog/2018/06/27/fp-kotlin-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-06-27-fp-kotlin-arrow.md","source":"@site/content/blog/2018-06-27-fp-kotlin-arrow.md","title":"Functional Programming in Kotlin with Arrow by Emmanuel Nhan","description":"@nhanmanu introduces Kotlin and how it is a good fit for functional programming. The talk goes through some interesting features of Kotlin, then show how to use them to enter the world of Higher Kinds and Typeclasses. In the last part, we explore some Arrow capabilities & built-in syntax, using validation as an example.","date":"2018-06-27T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks"}],"readingTime":0.27,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Programming in Kotlin with Arrow by Emmanuel Nhan","image":"https://image.slidesharecdn.com/fpkotlinsunnytech-180628144002/95/functional-programming-in-kotlin-with-arrow-sunnytech-2018-1-638.jpg","category":"slidedecks","tags":["core","slidedecks"],"link":"https://www.slideshare.net/EmmanuelNhan/functional-programming-in-kotlin-with-arrow-sunnytech-2018","event":"Sunny Tech, Montpellier"},"unlisted":false,"prevItem":{"title":"Arrow and Functional Programming for Kotlin Developers","permalink":"/community/blog/2018/07/24/arrow-fp-kotlin"},"nextItem":{"title":"Arrow 101\u200a - \u200aBuilding an Android app using Functional Programming","permalink":"/community/blog/2018/06/24/arrow-101"}},"content":"[@nhanmanu](https://twitter.com/nhanmanu) introduces Kotlin and how it is a good fit for functional programming. The talk goes through some interesting features of Kotlin, then show how to use them to enter the world of Higher Kinds and Typeclasses. In the last part, we explore some Arrow capabilities & built-in syntax, using validation as an example."},{"id":"/2018/06/24/arrow-101","metadata":{"permalink":"/community/blog/2018/06/24/arrow-101","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-06-24-arrow-101.md","source":"@site/content/blog/2018-06-24-arrow-101.md","title":"Arrow 101\u200a - \u200aBuilding an Android app using Functional Programming","description":"Leandro Ferreira presents how to build a simple app using Arrow and how to implement solutions with Semigroups.","date":"2018-06-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.17,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Arrow 101\u200a - \u200aBuilding an Android app using Functional Programming","image":"https://cdn-images-1.medium.com/max/2000/1*7HJJpOQE8M1-xXW0_5eePQ.png","category":"articles","tags":["core","articles"],"link":"https://medium.com/@lehen01/arrow-101-building-an-android-app-using-functional-programming-fe959675d96d"},"unlisted":false,"prevItem":{"title":"Functional Programming in Kotlin with Arrow by Emmanuel Nhan","permalink":"/community/blog/2018/06/27/fp-kotlin-arrow"},"nextItem":{"title":"State of the functional ecosystem in Kotlin: Mid 2018 checkup","permalink":"/community/blog/2018/06/24/state-ecosystem"}},"content":"[Leandro Ferreira](https://twitter.com/mLeandroBF) presents how to build a simple app using Arrow and how to implement solutions with Semigroups.\\n\\n[Arrow 101\u200a\u2014\u200aBuilding an Android app using Functional Programming](https://medium.com/@lehen01/arrow-101-building-an-android-app-using-functional-programming-fe959675d96d)\\n\\n[Arrow 101\u200a\u2014\u200aModelling a real world problem with Semigroups](https://medium.com/@lehen01/arrow-101-modelling-a-real-world-problem-with-semigroups-d8f22cdf54c)"},{"id":"/2018/06/24/state-ecosystem","metadata":{"permalink":"/community/blog/2018/06/24/state-ecosystem","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-06-24-state-ecosystem.md","source":"@site/content/blog/2018-06-24-state-ecosystem.md","title":"State of the functional ecosystem in Kotlin: Mid 2018 checkup","description":"This talk focuses on the day-to-day problems Arrow solves, from small ideas to big concepts.","date":"2018-06-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"incubator","permalink":"/community/blog/tags/incubator"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"State of the functional ecosystem in Kotlin: Mid 2018 checkup","image":"https://img.youtube.com/vi/q_1xPYQLyaU/maxresdefault.jpg","category":"videos","tags":["core","optics","fx","incubator","videos"],"link":"https://www.youtube.com/watch?v=q_1xPYQLyaU","event":"Conference for Kotliners, Budapest"},"unlisted":false,"prevItem":{"title":"Arrow 101\u200a - \u200aBuilding an Android app using Functional Programming","permalink":"/community/blog/2018/06/24/arrow-101"},"nextItem":{"title":"Higher Kinded Types in a Lower Kinded Language by Jacob Bass","permalink":"/community/blog/2018/06/22/hk-types"}},"content":"This talk focuses on the day-to-day problems Arrow solves, from small ideas to big concepts.\\n\\nIt includes an overview of all the modules available, and some of the 3rd party libraries made by the community."},{"id":"/2018/06/22/hk-types","metadata":{"permalink":"/community/blog/2018/06/22/hk-types","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-06-22-hk-types.md","source":"@site/content/blog/2018-06-22-hk-types.md","title":"Higher Kinded Types in a Lower Kinded Language by Jacob Bass","description":"It\'s hard coming back down to the earth of a JVM based language after spending time with Haskell and OCaml. This talk will discuss functional programming in Kotlin with the Arrow library, how the abstractions it provides can improve your code, and how this magic that provides higher-kinded types works under the hood.","date":"2018-06-22T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.265,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Higher Kinded Types in a Lower Kinded Language by Jacob Bass","image":"https://img.youtube.com/vi/ERM0mBPNLHc/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=ERM0mBPNLHc","event":"Yow! Lambda Jam, Sydney, Australia"},"unlisted":false,"prevItem":{"title":"State of the functional ecosystem in Kotlin: Mid 2018 checkup","permalink":"/community/blog/2018/06/24/state-ecosystem"},"nextItem":{"title":"1/n - How do I\u2026 in FP: Validation","permalink":"/community/blog/2018/04/23/how-do-i"}},"content":"It\'s hard coming back down to the earth of a JVM based language after spending time with Haskell and OCaml. This talk will discuss functional programming in Kotlin with the Arrow library, how the abstractions it provides can improve your code, and how this magic that provides higher-kinded types works under the hood."},{"id":"/2018/04/23/how-do-i","metadata":{"permalink":"/community/blog/2018/04/23/how-do-i","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-04-23-how-do-i.md","source":"@site/content/blog/2018-04-23-how-do-i.md","title":"1/n - How do I\u2026 in FP: Validation","description":"Emmanuel Nhan showcases different approaches to validation including examples for ValidatedNel from Arrow in this great and in depth post using Kafka Streams Config parameters as example.","date":"2018-04-23T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"tutorials","permalink":"/community/blog/tags/tutorials"}],"readingTime":0.175,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"1/n - How do I\u2026 in FP: Validation","image":"https://images.unsplash.com/photo-1518169811655-27c3a4327016?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=600&fit=max&ixid=eyJhcHBfaWQiOjExNzczfQ&s=383b467064497d356a0b05b3a3d180be","category":"tutorials","tags":["core","tutorials"],"link":"https://www.enhan.eu/how-to-in-fp/"},"unlisted":false,"prevItem":{"title":"Higher Kinded Types in a Lower Kinded Language by Jacob Bass","permalink":"/community/blog/2018/06/22/hk-types"},"nextItem":{"title":"Android Functional Validation","permalink":"/community/blog/2018/04/14/android-functional-validation"}},"content":"[Emmanuel Nhan](https://www.enhan.eu/author/enhan/) showcases different approaches to validation including examples for `ValidatedNel` from Arrow in this great and in depth post using Kafka Streams Config parameters as example.\\n\\n[1/n - How do I\u2026 in FP: Validation](https://www.enhan.eu/how-to-in-fp/)"},{"id":"/2018/04/14/android-functional-validation","metadata":{"permalink":"/community/blog/2018/04/14/android-functional-validation","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-04-14-android-functional-validation.md","source":"@site/content/blog/2018-04-14-android-functional-validation.md","title":"Android Functional Validation","description":"@dcampogiani explores some data types in Arrow and uses them to validate a form on Android.","date":"2018-04-14T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"tutorials","permalink":"/community/blog/tags/tutorials"}],"readingTime":0.135,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Android Functional Validation","image":"https://i.vimeocdn.com/video/713283357_1280x720.jpg","category":"tutorials","tags":["core","tutorials"],"link":"https://player.vimeo.com/video/279931528"},"unlisted":false,"prevItem":{"title":"1/n - How do I\u2026 in FP: Validation","permalink":"/community/blog/2018/04/23/how-do-i"},"nextItem":{"title":"Introduction to Kotlin Arrow by Jacob Bass","permalink":"/community/blog/2018/03/26/kotlin-arrow"}},"content":"[@dcampogiani](https://github.com/dcampogiani) explores some data types in Arrow and uses them to validate a form on Android.\\n\\n[Video (in italian)](https://player.vimeo.com/video/279931528)\\n\\n* [Introduction](http://danielecampogiani.com/blog/2018/02/android-functional-validation-1-intro/)\\n* [Option](http://danielecampogiani.com/blog/2018/02/android-functional-validation-2-option/)\\n* [Either](http://danielecampogiani.com/blog/2018/02/android-functional-validation-3-either/)\\n* [Validated](http://danielecampogiani.com/blog/2018/02/android-functional-validation-4-validated/)"},{"id":"/2018/03/26/kotlin-arrow","metadata":{"permalink":"/community/blog/2018/03/26/kotlin-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-03-26-kotlin-arrow.md","source":"@site/content/blog/2018-03-26-kotlin-arrow.md","title":"Introduction to Kotlin Arrow by Jacob Bass","description":"@bassjacob goes through how Funktionale and Kategory merged into Arrow, consolidating two of the most popular FP libraries in the Kotlin space into one powerhouse. The talk is an introduction to some FP concepts, how the libraries work, what features they bring to the table and where you might use them in your code.","date":"2018-03-26T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.27,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Introduction to Kotlin Arrow by Jacob Bass","image":"https://img.youtube.com/vi/tM2wEI-e80E/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=tM2wEI-e80E","event":"Kotlin Meetup, Sydney"},"unlisted":false,"prevItem":{"title":"Android Functional Validation","permalink":"/community/blog/2018/04/14/android-functional-validation"},"nextItem":{"title":"It\'s all about morphisms","permalink":"/community/blog/2018/03/21/morphisms"}},"content":"[@bassjacob](https://github.com/bassjacob) goes through how Funktionale and Kategory merged into Arrow, consolidating two of the most popular FP libraries in the Kotlin space into one powerhouse. The talk is an introduction to some FP concepts, how the libraries work, what features they bring to the table and where you might use them in your code."},{"id":"/2018/03/21/morphisms","metadata":{"permalink":"/community/blog/2018/03/21/morphisms","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-03-21-morphisms.md","source":"@site/content/blog/2018-03-21-morphisms.md","title":"It\'s all about morphisms","description":"@uberto gives a gentle introduction to Category Theory for programmers used to OOP but interested in Functional Programming. No Haskell knowledge required. We will explain main concepts behind functional programming with many diagrams and simple metaphors and examples. Some code will clarify how to translate these ideas in programs.","date":"2018-03-21T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.245,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"It\'s all about morphisms","image":"https://img.youtube.com/vi/Eq8dv4H3RTE/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=Eq8dv4H3RTE","event":"Voxxed Days, Vienna"},"unlisted":false,"prevItem":{"title":"Introduction to Kotlin Arrow by Jacob Bass","permalink":"/community/blog/2018/03/26/kotlin-arrow"},"nextItem":{"title":"Optics and Type Classes in Arrow","permalink":"/community/blog/2018/01/17/optics-type-classes-arrow"}},"content":"[@uberto](https://github.com/uberto) gives a gentle introduction to Category Theory for programmers used to OOP but interested in Functional Programming. No Haskell knowledge required. We will explain main concepts behind functional programming with many diagrams and simple metaphors and examples. Some code will clarify how to translate these ideas in programs."},{"id":"/2018/01/17/optics-type-classes-arrow","metadata":{"permalink":"/community/blog/2018/01/17/optics-type-classes-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2018-01-17-optics-type-classes-arrow.md","source":"@site/content/blog/2018-01-17-optics-type-classes-arrow.md","title":"Optics and Type Classes in Arrow","description":"@msya explains how to use various optics and type classes in Arrow. He discusses optics such as","date":"2018-01-17T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"optics","permalink":"/community/blog/tags/optics"},{"label":"slidedecks","permalink":"/community/blog/tags/slidedecks"}],"readingTime":0.215,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Optics and Type Classes in Arrow","image":"https://speakerd.s3.amazonaws.com/presentations/4b938d99415a416c8f908ac5302a66cb/slide_0.jpg","category":"slidedecks","tags":["core","optics","slidedecks"],"event":"Kotlin Brooklyn Meetup","link":"https://speakerdeck.com/heyitsmohit/functional-programming-with-arrow"},"unlisted":false,"prevItem":{"title":"It\'s all about morphisms","permalink":"/community/blog/2018/03/21/morphisms"},"nextItem":{"title":"Functional Programming in Kotlin with Arrow","permalink":"/community/blog/2017/11/29/fp-kotlin-arrow"}},"content":"[@msya](https://github.com/msya) explains how to use various optics and type classes in Arrow. He discusses optics such as\\n[`Lens`](https://arrow-kt.io/learn/immutable-data/lens/) and [`Iso`](https://arrow-kt.io/learn/immutable-data/prism-iso/). He also goes over the purpose for type classes and how [KEEP-87](https://github.com/Kotlin/KEEP/pull/87) will make it easier to implement them.\\n\\n[Functional Programming with Arrow](https://speakerdeck.com/heyitsmohit/functional-programming-with-arrow)"},{"id":"/2017/11/29/fp-kotlin-arrow","metadata":{"permalink":"/community/blog/2017/11/29/fp-kotlin-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-29-fp-kotlin-arrow.md","source":"@site/content/blog/2017-11-29-fp-kotlin-arrow.md","title":"Functional Programming in Kotlin with Arrow","description":"A rundown of all the features included in the library, focusing on implementation details.","date":"2017-11-29T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Programming in Kotlin with Arrow","image":"https://img.youtube.com/vi/IL5XzaCMKpQ/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=IL5XzaCMKpQ","event":"Lambda World, C\xe1diz"},"unlisted":false,"prevItem":{"title":"Optics and Type Classes in Arrow","permalink":"/community/blog/2018/01/17/optics-type-classes-arrow"},"nextItem":{"title":"Building a DSL\u2026 in Kotlin","permalink":"/community/blog/2017/11/24/building-dsl-kotlin"}},"content":"A rundown of all the features included in the library, focusing on implementation details."},{"id":"/2017/11/24/building-dsl-kotlin","metadata":{"permalink":"/community/blog/2017/11/24/building-dsl-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-24-building-dsl-kotlin.md","source":"@site/content/blog/2017-11-24-building-dsl-kotlin.md","title":"Building a DSL\u2026 in Kotlin","description":"Make DSLs stack safe, composable and reusable under different runtime requirements thanks to Arrow.","date":"2017-11-24T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.07,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Building a DSL\u2026 in Kotlin","image":"https://img.youtube.com/vi/qGef3sFAIxU/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=qGef3sFAIxU","event":"droidconSF, San Francisco"},"unlisted":false,"prevItem":{"title":"Functional Programming in Kotlin with Arrow","permalink":"/community/blog/2017/11/29/fp-kotlin-arrow"},"nextItem":{"title":"Happy path: Kotlin + Actors + Arrow","permalink":"/community/blog/2017/11/22/happy-path"}},"content":"Make DSLs stack safe, composable and reusable under different runtime requirements thanks to Arrow."},{"id":"/2017/11/22/happy-path","metadata":{"permalink":"/community/blog/2017/11/22/happy-path","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-22-happy-path.md","source":"@site/content/blog/2017-11-22-happy-path.md","title":"Happy path: Kotlin + Actors + Arrow","description":"@javipacheco creates a Proof of Concept architecture for Android using the Actor pattern and modelling the domain with Either.","date":"2017-11-22T00:00:00.000Z","tags":[],"readingTime":0.13,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Happy path: Kotlin + Actors + Arrow","image":"https://cdn-images-1.medium.com/max/600/1*kF_bpeNe0THMssFEa2enYA.jpeg","category":"articles","tag":["core","articles"],"link":"https://medium.com/@javipacheco/happy-path-kotlin-actors-arrow-proof-of-concept-322e9099d2ea"},"unlisted":false,"prevItem":{"title":"Building a DSL\u2026 in Kotlin","permalink":"/community/blog/2017/11/24/building-dsl-kotlin"},"nextItem":{"title":"Architectures Using Functional Programming Concepts","permalink":"/community/blog/2017/11/17/architectures"}},"content":"[@javipacheco](https://github.com/javipacheco) creates a Proof of Concept architecture for Android using the Actor pattern and modelling the domain with [`Either`](https://apidocs.arrow-kt.io/arrow-core/arrow.core/-either/index.html).\\n\\n[Happy Path: Kotlin + Actors + Arrow](https://medium.com/@javipacheco/happy-path-kotlin-actors-arrow-proof-of-concept-322e9099d2ea)"},{"id":"/2017/11/17/architectures","metadata":{"permalink":"/community/blog/2017/11/17/architectures","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-17-architectures.md","source":"@site/content/blog/2017-11-17-architectures.md","title":"Architectures Using Functional Programming Concepts","description":"Introductory talk to Functional architectures to be built on top of Arrow.","date":"2017-11-17T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.06,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Architectures Using Functional Programming Concepts","image":"https://img.youtube.com/vi/qI1ctQ0293o/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=qI1ctQ0293o","event":"KotlinConf, San Francisco"},"unlisted":false,"prevItem":{"title":"Happy path: Kotlin + Actors + Arrow","permalink":"/community/blog/2017/11/22/happy-path"},"nextItem":{"title":"Kotlin for the Pragmatic Functionalist","permalink":"/community/blog/2017/11/09/pragmatic-functionalist"}},"content":"Introductory talk to Functional architectures to be built on top of Arrow."},{"id":"/2017/11/09/pragmatic-functionalist","metadata":{"permalink":"/community/blog/2017/11/09/pragmatic-functionalist","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-09-pragmatic-functionalist.md","source":"@site/content/blog/2017-11-09-pragmatic-functionalist.md","title":"Kotlin for the Pragmatic Functionalist","description":"An introduction to Arrow and the enhancements it brings to Kotlin\'s standard library.","date":"2017-11-09T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.065,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Kotlin for the Pragmatic Functionalist","image":"https://img.youtube.com/vi/s9oMED6ZikQ/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=s9oMED6ZikQ","event":"KotlinConf, San Francisco"},"unlisted":false,"prevItem":{"title":"Architectures Using Functional Programming Concepts","permalink":"/community/blog/2017/11/17/architectures"},"nextItem":{"title":"Functional Programming in Kotlin","permalink":"/community/blog/2017/11/02/fp-kotlin"}},"content":"An introduction to Arrow and the enhancements it brings to Kotlin\'s standard library."},{"id":"/2017/11/02/fp-kotlin","metadata":{"permalink":"/community/blog/2017/11/02/fp-kotlin","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-11-02-fp-kotlin.md","source":"@site/content/blog/2017-11-02-fp-kotlin.md","title":"Functional Programming in Kotlin","description":"An ongoing blog series introducing Functional Programming architectures from scratch","date":"2017-11-02T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"fx","permalink":"/community/blog/tags/fx"},{"label":"mtl","permalink":"/community/blog/tags/mtl"},{"label":"tutorials","permalink":"/community/blog/tags/tutorials"}],"readingTime":0.145,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional Programming in Kotlin","image":"https://cdn-images-1.medium.com/max/600/1*NpQ5mqoY4SH5iwsWG35RqQ.jpeg","category":"tutorials","tags":["core","fx","mtl","tutorials"],"link":"https://medium.com/@JorgeCastilloPr/kotlin-functional-programming-does-it-make-sense-36ad07e6bacf"},"unlisted":false,"prevItem":{"title":"Kotlin for the Pragmatic Functionalist","permalink":"/community/blog/2017/11/09/pragmatic-functionalist"},"nextItem":{"title":"Functional approach to Android architecture using Kotlin","permalink":"/community/blog/2017/10/20/functional-approach"}},"content":"An ongoing blog series introducing Functional Programming architectures from scratch\\n\\n[Kotlin Functional Programming: Does it make sense?](https://medium.com/@JorgeCastilloPr/kotlin-functional-programming-does-it-make-sense-36ad07e6bacf)\\n\\n[Kotlin Functional Programming I: Monad Stack](https://medium.com/@JorgeCastilloPr/kotlin-functional-programming-i-monad-stack-518d1bd8fbee)\\n\\n[Kotlin Functional Programming II: Monad Transformers](https://medium.com/@JorgeCastilloPr/kotlin-functional-programming-ii-monad-transformers-b1f020f14dd8)"},{"id":"/2017/10/20/functional-approach","metadata":{"permalink":"/community/blog/2017/10/20/functional-approach","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-10-20-functional-approach.md","source":"@site/content/blog/2017-10-20-functional-approach.md","title":"Functional approach to Android architecture using Kotlin","description":"Move side effects to the edges of the system, implement a functional oriented architecture for Android apps based on purity.","date":"2017-10-20T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"videos","permalink":"/community/blog/tags/videos"}],"readingTime":0.1,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Functional approach to Android architecture using Kotlin","image":"https://img.youtube.com/vi/qGef3sFAIxU/maxresdefault.jpg","category":"videos","tags":["core","videos"],"link":"https://www.youtube.com/watch?v=qGef3sFAIxU","event":"Mobilization 7, \u0141\xf3d\u017a"},"unlisted":false,"prevItem":{"title":"Functional Programming in Kotlin","permalink":"/community/blog/2017/11/02/fp-kotlin"},"nextItem":{"title":"Handling exceptions in Arrow","permalink":"/community/blog/2017/09/17/handling-exceptions-arrow"}},"content":"Move side effects to the edges of the system, implement a functional oriented architecture for Android apps based on purity."},{"id":"/2017/09/17/handling-exceptions-arrow","metadata":{"permalink":"/community/blog/2017/09/17/handling-exceptions-arrow","editUrl":"https://github.com/arrow-kt/arrow-website/edit/main/content/blog/2017-09-17-handling-exceptions-arrow.md","source":"@site/content/blog/2017-09-17-handling-exceptions-arrow.md","title":"Handling exceptions in Arrow","description":"@uris77 explains how to use Try in real world examples.","date":"2017-09-17T00:00:00.000Z","tags":[{"label":"core","permalink":"/community/blog/tags/core"},{"label":"articles","permalink":"/community/blog/tags/articles"}],"readingTime":0.095,"hasTruncateMarker":false,"authors":[],"frontMatter":{"title":"Handling exceptions in Arrow","image":"/img/blog-image-header.png","category":"articles","tags":["core","articles"],"link":"https://www.spantree.net/blog/2017/09/15/kotlin-exception-handling-with-kategory.html"},"unlisted":false,"prevItem":{"title":"Functional approach to Android architecture using Kotlin","permalink":"/community/blog/2017/10/20/functional-approach"}},"content":"[@uris77](https://github.com/uris77) explains how to use [Try](https://arrow-kt.io/docs/apidocs/arrow-core-data/arrow.core/-try/) in real world examples.\\n\\n[Handling Kotlin Exceptions with Arrow \u2013 A Functional Approach](https://www.spantree.net/blog/2017/09/15/kotlin-exception-handling-with-kategory.html)"}]}}')}}]); \ No newline at end of file diff --git a/assets/js/e9746b95.1c5c11a1.js b/assets/js/e9746b95.47741fed.js similarity index 76% rename from assets/js/e9746b95.1c5c11a1.js rename to assets/js/e9746b95.47741fed.js index 244ee31e..fe979c25 100644 --- a/assets/js/e9746b95.1c5c11a1.js +++ b/assets/js/e9746b95.47741fed.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[6722],{59585:t=>{t.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":46,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/2","page":2,"postsPerPage":8,"totalPages":6,"totalCount":46,"previousPage":"/community/blog/tags/articles","nextPage":"/community/blog/tags/articles/page/3","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[6722],{59585:t=>{t.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":47,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/2","page":2,"postsPerPage":8,"totalPages":6,"totalCount":47,"previousPage":"/community/blog/tags/articles","nextPage":"/community/blog/tags/articles/page/3","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/ec42f770.4aa586b9.js b/assets/js/ec42f770.a779447d.js similarity index 82% rename from assets/js/ec42f770.4aa586b9.js rename to assets/js/ec42f770.a779447d.js index 12e7e56f..a8fde634 100644 --- a/assets/js/ec42f770.4aa586b9.js +++ b/assets/js/ec42f770.a779447d.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[4529],{79660:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/6","page":6,"postsPerPage":8,"totalPages":14,"totalCount":106,"previousPage":"/community/blog/page/5","nextPage":"/community/blog/page/7","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[4529],{79660:e=>{e.exports=JSON.parse('{"metadata":{"permalink":"/community/blog/page/6","page":6,"postsPerPage":8,"totalPages":14,"totalCount":107,"previousPage":"/community/blog/page/5","nextPage":"/community/blog/page/7","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/f1e8344b.1778af1a.js b/assets/js/f1e8344b.7a54a9b0.js similarity index 76% rename from assets/js/f1e8344b.1778af1a.js rename to assets/js/f1e8344b.7a54a9b0.js index 3d1358c9..8116d781 100644 --- a/assets/js/f1e8344b.1778af1a.js +++ b/assets/js/f1e8344b.7a54a9b0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[5022],{4917:a=>{a.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":46,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/3","page":3,"postsPerPage":8,"totalPages":6,"totalCount":46,"previousPage":"/community/blog/tags/articles/page/2","nextPage":"/community/blog/tags/articles/page/4","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[5022],{4917:a=>{a.exports=JSON.parse('{"tag":{"label":"articles","permalink":"/community/blog/tags/articles","allTagsPath":"/community/blog/tags","count":47,"unlisted":false},"listMetadata":{"permalink":"/community/blog/tags/articles/page/3","page":3,"postsPerPage":8,"totalPages":6,"totalCount":47,"previousPage":"/community/blog/tags/articles/page/2","nextPage":"/community/blog/tags/articles/page/4","blogDescription":"Blog","blogTitle":"Blog"}}')}}]); \ No newline at end of file diff --git a/assets/js/main.7f3062ff.js b/assets/js/main.7f3062ff.js new file mode 100644 index 00000000..ad53bd55 --- /dev/null +++ b/assets/js/main.7f3062ff.js @@ -0,0 +1,2 @@ +/*! For license information please see main.7f3062ff.js.LICENSE.txt */ +(self.webpackChunkarrow_website=self.webpackChunkarrow_website||[]).push([[179],{1728:(e,t,n)=>{"use strict";function r(e){var t,n,o="";if("string"==typeof e||"number"==typeof e)o+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;to});const o=function(){for(var e,t,n=0,o="";n{"use strict";n.d(t,{Z:()=>p});n(67294);var r=n(68356),o=n.n(r),a=n(16887);const i={"002df74d":[()=>n.e(874).then(n.bind(n,20570)),"@site/content/blog/2021-02-10-advanced-fp-enterprise-bee-optics.md",20570],"0135f28e":[()=>n.e(3524).then(n.bind(n,25320)),"@site/content/blog/2019-03-12-immutable-conv-1.md?truncated=true",25320],"01a85c17":[()=>Promise.all([n.e(532),n.e(4013)]).then(n.bind(n,91223)),"@theme/BlogTagsListPage",91223],"0269e636":[()=>n.e(2188).then(n.bind(n,17939)),"@site/content/blog/2017-11-09-pragmatic-functionalist.md",17939],"0347038e":[()=>n.e(5621).then(n.bind(n,91309)),"@site/content/blog/2018-06-27-fp-kotlin-arrow.md",91309],"04418e1a":[()=>n.e(2291).then(n.bind(n,54807)),"@site/content/blog/2021-04-11-your-own-custom-spring-data-repository.md",54807],"04879efd":[()=>n.e(534).then(n.bind(n,80691)),"@site/content/blog/2021-04-01-arrow-0-12-0-0-13-1-release.md?truncated=true",80691],"04f4be93":[()=>n.e(4304).then(n.bind(n,56265)),"@site/content/blog/2021-01-20-fp-concepts-with-arrow.md",56265],"0701fb28":[()=>n.e(565).then(n.t.bind(n,60396,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-page-6-cae.json",60396],"078c875c":[()=>n.e(2394).then(n.bind(n,80509)),"@site/content/docs/learn/coroutines/parallel.md",80509],"07de05bd":[()=>n.e(4690).then(n.bind(n,39706)),"@site/content/docs/learn/quickstart/migration.md",39706],"0804e80a":[()=>n.e(5666).then(n.bind(n,15145)),"@site/content/blog/2018-01-17-optics-type-classes-arrow.md?truncated=true",15145],"090b0fad":[()=>n.e(5557).then(n.bind(n,58527)),"@site/content/blog/2020-06-16-type-proofs-fp-kotlin-talk.md",58527],"09a739ec":[()=>n.e(1868).then(n.bind(n,7816)),"@site/content/docs/learn/typed-errors/own-error-types.md",7816],"09ddf926":[()=>n.e(6496).then(n.t.bind(n,85979,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-articles-page-5-5e9.json",85979],"0c39f3a0":[()=>n.e(4869).then(n.t.bind(n,25794,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-intellij-46c.json",25794],"0e213cc9":[()=>Promise.all([n.e(532),n.e(2578)]).then(n.bind(n,48818)),"@site/src/pages/training/index.ts",48818],"0fd4d2f1":[()=>n.e(5265).then(n.bind(n,84723)),"@site/content/blog/2020-02-26-fp-with-kotlin-arrow.md",84723],"0fd538b3":[()=>n.e(3380).then(n.t.bind(n,95799,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-videos-page-5-b36.json",95799],"10c29de9":[()=>n.e(2813).then(n.bind(n,81847)),"@site/content/blog/2020-10-28-arrow-promoted-to-adopt.md?truncated=true",81847],"110a6aeb":[()=>n.e(7485).then(n.bind(n,96967)),"@site/content/blog/2017-11-24-building-dsl-kotlin.md?truncated=true",96967],"114d6d85":[()=>n.e(2620).then(n.bind(n,27584)),"@site/content/blog/2022-05-30-super-charge-build-arrow-analysis.md",27584],"117f818a":[()=>n.e(2063).then(n.t.bind(n,54706,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-mtl-13c.json",54706],"131c2a83":[()=>n.e(2087).then(n.bind(n,73241)),"@site/content/blog/2020-03-02-io-integration-kotlinx-coroutines.md",73241],"138e0e15":[()=>n.e(9524).then(n.t.bind(n,80536,19)),"@generated/@easyops-cn/docusaurus-search-local/default/__plugin.json",80536],"139c8f8a":[()=>n.e(158).then(n.bind(n,13217)),"@site/content/blog/2023-05-04-arrow-trajectory-kotlinconf.md",13217],"14458dc8":[()=>n.e(3338).then(n.t.bind(n,47150,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-tutorials-1d2.json",47150],"148a328e":[()=>n.e(7847).then(n.t.bind(n,6290,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-13-ccb.json",6290],"14fa83de":[()=>n.e(9440).then(n.t.bind(n,15584,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-page-10-2bc.json",15584],"158a5b8d":[()=>n.e(6567).then(n.bind(n,97345)),"@site/content/blog/2021-11-30-functional-programming-kotlin-exploring-arrow.md?truncated=true",97345],"15f7c799":[()=>n.e(7603).then(n.bind(n,31657)),"@site/content/docs/learn/immutable-data/intro.md",31657],17896441:[()=>Promise.all([n.e(532),n.e(583),n.e(7918)]).then(n.bind(n,3389)),"@theme/DocItem",3389],"17cd98fd":[()=>n.e(6684).then(n.t.bind(n,86050,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-4-926.json",86050],"17d6e564":[()=>n.e(3946).then(n.bind(n,5610)),"@site/content/blog/2022-06-14-arrow-kotlin-dev-day.md?truncated=true",5610],"199e9947":[()=>n.e(3120).then(n.t.bind(n,28817,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-3-457.json",28817],"19f0f562":[()=>Promise.all([n.e(532),n.e(3394)]).then(n.bind(n,53194)),"@site/src/pages/community/events/index.ts",53194],"1a4e3797":[()=>Promise.all([n.e(532),n.e(7920)]).then(n.bind(n,51473)),"@theme/SearchPage",51473],"1aa28852":[()=>n.e(5462).then(n.bind(n,70106)),"@site/content/blog/2020-01-29-parallel-processing-the-functional-way-with-arrow-fx.md",70106],"1be2714d":[()=>n.e(2601).then(n.bind(n,64129)),"@site/content/blog/2018-06-24-arrow-101.md?truncated=true",64129],"1bfd21bd":[()=>n.e(7233).then(n.bind(n,1090)),"@site/content/blog/2019-01-03-getting-started.md",1090],"1df93b7f":[()=>Promise.all([n.e(532),n.e(7311),n.e(3237)]).then(n.bind(n,83666)),"@site/src/pages/index.tsx",83666],"1e184c5a":[()=>n.e(3346).then(n.bind(n,52215)),"@site/content/blog/2022-12-01-actions-as-data.md",52215],"1e6abe3b":[()=>n.e(8546).then(n.bind(n,75210)),"@site/content/blog/2021-08-12-arrow-of-outrageous-error-handling.md?truncated=true",75210],"1e83a7ad":[()=>n.e(334).then(n.bind(n,23450)),"@site/content/docs/learn/design/domain-modeling.md",23450],"21169d6c":[()=>n.e(2469).then(n.bind(n,75517)),"@site/content/blog/2020-04-08-writing-compiler-plugin-with-with-arrow-meta.md?truncated=true",75517],"21b3bea6":[()=>n.e(8476).then(n.bind(n,42547)),"@site/content/blog/2022-06-14-arrow-kotlin-dev-day.md",42547],"21bb14e6":[()=>n.e(3425).then(n.bind(n,58454)),"@site/content/blog/2022-05-30-extending-kotlinx-serialization-functionality-arrow-meta.md",58454],"2241301a":[()=>n.e(3110).then(n.bind(n,29284)),"@site/content/blog/2021-02-05-advanced-fp-enterprise-bee-typeclasses.md",29284],22533556:[()=>n.e(7637).then(n.t.bind(n,23988,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-videos-bf4.json",23988],"22a6a5d0":[()=>n.e(5837).then(n.bind(n,48964)),"@site/content/blog/2021-02-19-advanced-fp-enterprise-bee-state.md?truncated=true",48964],"23b01488":[()=>n.e(5458).then(n.bind(n,81959)),"@site/content/blog/2021-04-13-functional-domain-modeling-kotlin-validation.md",81959],"242a7851":[()=>n.e(7061).then(n.bind(n,76901)),"@site/content/blog/2022-05-30-super-charge-build-arrow-analysis.md?truncated=true",76901],"2438d417":[()=>n.e(7712).then(n.bind(n,93114)),"@site/content/docs/ecosystem/analysis/wrappers.md",93114],"24a5a52d":[()=>n.e(4855).then(n.t.bind(n,28128,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-557.json",28128],"24cd6a0b":[()=>n.e(7925).then(n.bind(n,80674)),"@site/content/blog/2022-03-10-domain-model-validation-in-kotlin-part-3.md?truncated=true",80674],"266a2368":[()=>Promise.all([n.e(532),n.e(9715)]).then(n.bind(n,42790)),"@site/content/docs/learn/immutable-data/index.md",42790],"26a89259":[()=>n.e(3232).then(n.bind(n,30233)),"@site/content/docs/ecosystem/suspendapp/kafka.md",30233],27938626:[()=>Promise.all([n.e(532),n.e(4872)]).then(n.bind(n,11127)),"@site/content/docs/learn/quickstart/index.md",11127],"27d81f49":[()=>n.e(554).then(n.t.bind(n,37283,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-page-4-338.json",37283],"27fc5ece":[()=>n.e(778).then(n.t.bind(n,76112,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-2-fda.json",76112],"296f827d":[()=>n.e(8340).then(n.bind(n,2402)),"@site/content/blog/2020-10-28-technology-radar-promotes-arrow.md",2402],"2bf35fb0":[()=>n.e(1677).then(n.bind(n,16981)),"@site/content/blog/2018-06-27-fp-kotlin-arrow.md?truncated=true",16981],"2c6086f0":[()=>n.e(7386).then(n.bind(n,88864)),"@site/content/blog/2022-03-03-domain-model-validation-in-kotlin-part-2.md",88864],"2d2a00ed":[()=>n.e(8946).then(n.t.bind(n,86932,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-fx-page-3-6ce.json",86932],"2dfd0bba":[()=>n.e(9601).then(n.bind(n,11802)),"@site/content/docs/learn/immutable-data/lens.md",11802],"2e84a98d":[()=>n.e(1002).then(n.bind(n,53011)),"@site/content/docs/learn/immutable-data/reflection.md",53011],"303d9af1":[()=>n.e(2404).then(n.bind(n,53846)),"@site/content/blog/2020-11-19-fight-complexity-with-functional-programming.md?truncated=true",53846],"3154f9e3":[()=>n.e(7071).then(n.bind(n,21885)),"@site/content/blog/2019-06-04-keep-87-and-typeclasses.md",21885],"31a48727":[()=>n.e(3545).then(n.bind(n,42333)),"@site/content/docs/learn/collections-functions/memoize.md",42333],"320d88c4":[()=>n.e(3910).then(n.bind(n,39748)),"@site/content/docs/learn/quickstart/compose.md",39748],"331f011f":[()=>n.e(1409).then(n.bind(n,79301)),"@site/content/blog/2022-02-22-domain-model-validation-in-kotlin-part-1.md?truncated=true",79301],"334a2250":[()=>n.e(5026).then(n.bind(n,5438)),"@site/content/blog/2023-07-12-arrow-1-2-0.md",5438],"34db7f33":[()=>n.e(9054).then(n.bind(n,83647)),"@site/content/blog/2019-12-12-GOL-using-Kotlin-and-Arrow.md?truncated=true",83647],"36994c47":[()=>n.e(9208).then(n.t.bind(n,94468,19)),"@generated/docusaurus-plugin-content-blog/default/__plugin.json",94468],"38fcd5cd":[()=>n.e(7200).then(n.t.bind(n,55158,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-articles-page-4-d03.json",55158],"398180ae":[()=>n.e(9746).then(n.t.bind(n,94782,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-optics-32a.json",94782],"39a90ed7":[()=>n.e(5314).then(n.bind(n,48899)),"@site/content/blog/2022-05-18-functional-programming-kotlin-exploring-arrow-ties-van-de-ven.md?truncated=true",48899],"3a62e69e":[()=>n.e(9414).then(n.t.bind(n,66745,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-slidedecks-e03.json",66745],"3a78a4c8":[()=>n.e(5575).then(n.bind(n,34548)),"@site/content/blog/2019-12-15-Kotlin-coroutines-with-arrow-fx.md",34548],"3a8ba992":[()=>n.e(9736).then(n.bind(n,36656)),"@site/content/blog/2019-08-08-kotlin-and-arrow-the-functional-way.md?truncated=true",36656],"3cf8b4e1":[()=>n.e(9775).then(n.t.bind(n,5936,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-11-252.json",5936],"3d4bf552":[()=>n.e(5600).then(n.bind(n,82606)),"@site/content/docs/learn/coroutines/concurrency-primitives.md",82606],"3fad6c11":[()=>n.e(9435).then(n.bind(n,34540)),"@site/content/blog/2021-02-26-advanced-fp-enterprise-bee-shiny-things.md",34540],40316950:[()=>n.e(7999).then(n.bind(n,47088)),"@site/content/blog/2018-06-24-state-ecosystem.md",47088],"416b553c":[()=>n.e(9277).then(n.bind(n,45779)),"@site/content/blog/2021-01-15-advanced-fp-enterprise-bee-applicatives.md?truncated=true",45779],"43fd0363":[()=>n.e(4178).then(n.bind(n,36252)),"@site/content/blog/2020-01-29-cleaner-composition-with-monad-comprehensions-arrow-fx.md?truncated=true",36252],"441eae9d":[()=>n.e(6963).then(n.bind(n,60152)),"@site/content/blog/2021-01-08-advanced-fp-enterprise-bee-traverse.md?truncated=true",60152],"446f920e":[()=>n.e(1768).then(n.bind(n,96350)),"@site/content/docs/learn/collections-functions/eval.md",96350],"45742c5c":[()=>n.e(374).then(n.t.bind(n,50996,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-articles-a82.json",50996],"4625a47e":[()=>n.e(9609).then(n.bind(n,72392)),"@site/content/blog/2017-11-17-architectures.md?truncated=true",72392],"464126ba":[()=>Promise.all([n.e(532),n.e(6028)]).then(n.bind(n,92886)),"@site/content/docs/ecosystem/analysis/quickstart.md",92886],"4672b915":[()=>Promise.all([n.e(532),n.e(8628)]).then(n.bind(n,11362)),"@site/content/docs/ecosystem/suspendapp/index.md",11362],"484a1ecc":[()=>n.e(2048).then(n.bind(n,33838)),"@site/content/blog/2023-04-17-typed-error-handling-in-kotlin.md",33838],"4904b505":[()=>n.e(1197).then(n.bind(n,23685)),"@site/content/blog/2021-01-13-functional-android.md?truncated=true",23685],"4a55457a":[()=>n.e(7212).then(n.bind(n,6114)),"@site/content/docs/learn/design/projects.md",6114],"4a7a7924":[()=>n.e(4326).then(n.bind(n,41613)),"@site/content/blog/2021-01-13-functional-android.md",41613],"4ad445d5":[()=>n.e(4417).then(n.bind(n,6299)),"@site/content/blog/2019-02-03-arrow-webflux.md?truncated=true",6299],"4b550b64":[()=>n.e(6116).then(n.bind(n,69561)),"@site/content/docs/ecosystem/analysis/conditions.md",69561],"4cb8daa7":[()=>n.e(9362).then(n.bind(n,84259)),"@site/content/docs/learn/immutable-data/optional.md",84259],"4cecac10":[()=>n.e(7778).then(n.bind(n,45881)),"@site/content/blog/2017-11-22-happy-path.md",45881],"4eed4483":[()=>Promise.all([n.e(532),n.e(2119)]).then(n.bind(n,95784)),"@site/src/pages/libraries/index.ts",95784],"4f356f76":[()=>n.e(5222).then(n.t.bind(n,37998,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-videos-page-4-ed3.json",37998],"4fb0528b":[()=>n.e(165).then(n.bind(n,29923)),"@site/content/blog/2024-02-28-arrow-1-2-3.md",29923],"517a3c97":[()=>n.e(9091).then(n.bind(n,71268)),"@site/content/docs/learn/coroutines/stm.md",71268],51994487:[()=>n.e(7218).then(n.t.bind(n,48413,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-7-473.json",48413],"51a052e4":[()=>n.e(7514).then(n.t.bind(n,46812,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-12-854.json",46812],"52188c1f":[()=>n.e(3769).then(n.bind(n,30095)),"@site/content/blog/2020-12-16-roll-your-own-computation-blocks-kotlin.md?truncated=true",30095],"5259f483":[()=>n.e(2593).then(n.bind(n,56121)),"@site/content/blog/2019-06-07-kotliners-arrow-fx.md?truncated=true",56121],"52ae0053":[()=>n.e(5751).then(n.bind(n,98516)),"@site/content/blog/2017-11-29-fp-kotlin-arrow.md",98516],"53addfd9":[()=>n.e(9050).then(n.t.bind(n,34067,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-page-7-7b9.json",34067],"540a0ff6":[()=>n.e(5743).then(n.t.bind(n,89456,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-incubator-f5a.json",89456],"54a7237b":[()=>n.e(9874).then(n.bind(n,26284)),"@site/content/blog/2020-04-06-template-oriented-programming.md?truncated=true",26284],"54cbfbf3":[()=>n.e(2682).then(n.bind(n,17336)),"@site/content/blog/2019-12-12-GOL-using-Kotlin-and-Arrow.md",17336],"553190da":[()=>n.e(877).then(n.bind(n,47161)),"@site/content/blog/2021-02-10-advanced-fp-enterprise-bee-optics.md?truncated=true",47161],"555c92b3":[()=>n.e(3138).then(n.bind(n,1226)),"@site/content/blog/2021-04-11-functional-domain-modeling-kotlin.md",1226],"55c5d214":[()=>n.e(479).then(n.bind(n,9671)),"@site/content/blog/2018-04-14-android-functional-validation.md",9671],"570749a6":[()=>n.e(5135).then(n.bind(n,7112)),"@site/content/blog/2019-04-11-introducing-arrow-playground.md",7112],"57bf43e8":[()=>n.e(450).then(n.t.bind(n,20525,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-page-9-156.json",20525],"57cddd56":[()=>n.e(9592).then(n.bind(n,8877)),"@site/content/blog/2020-04-06-template-oriented-programming-talk.md",8877],"59facd63":[()=>n.e(615).then(n.bind(n,41666)),"@site/content/blog/2023-05-04-data-transformation-kotlinconf.md?truncated=true",41666],"5a51fd5b":[()=>n.e(4538).then(n.bind(n,47684)),"@site/content/blog/2020-02-26-safer-programming-with-arrow.md?truncated=true",47684],"5aa8b1ec":[()=>n.e(3584).then(n.bind(n,43972)),"@site/content/blog/2018-10-05-kotlin-conf-fp-in-kotlin-with-arrow.md",43972],"5ae59fbd":[()=>n.e(2989).then(n.bind(n,8669)),"@site/content/docs/learn/quickstart/from-fp.md",8669],"5c6a8c07":[()=>n.e(2805).then(n.bind(n,34852)),"@site/content/blog/2022-07-01-exploring-arrow.md?truncated=true",34852],"5d0ba668":[()=>n.e(9210).then(n.bind(n,59893)),"@site/content/blog/2019-12-06-kotlinconf-arrow-meta.md",59893],"5d640db6":[()=>Promise.all([n.e(532),n.e(3169)]).then(n.bind(n,39867)),"@site/src/pages/libraries/libraries.tsx",39867],"5e49e099":[()=>n.e(1764).then(n.bind(n,53649)),"@site/content/blog/2019-12-06-kotlinconf-arrow-meta.md?truncated=true",53649],"5e95c892":[()=>n.e(9661).then(n.bind(n,41892)),"@theme/DocsRoot",41892],"5e9f5e1a":[()=>Promise.resolve().then(n.bind(n,36809)),"@generated/docusaurus.config",36809],"5f475e4d":[()=>n.e(4040).then(n.bind(n,67857)),"@site/content/blog/2019-02-10-imperative-functional-programming-arrow.md",67857],"604f2285":[()=>n.e(6689).then(n.bind(n,16)),"@site/content/blog/2018-11-30-hangman.md?truncated=true",16],"60a7885a":[()=>n.e(3157).then(n.bind(n,77270)),"@site/content/docs/learn/immutable-data/prism-iso.md",77270],"61b0aed5":[()=>n.e(3877).then(n.bind(n,10036)),"@site/content/blog/2022-03-10-domain-model-validation-in-kotlin-part-3.md",10036],"62450d00":[()=>n.e(5676).then(n.bind(n,82939)),"@site/content/blog/2018-11-24-ank.md?truncated=true",82939],"627645bc":[()=>n.e(2271).then(n.bind(n,33594)),"@site/content/blog/2020-01-29-parallel-processing-the-functional-way-with-arrow-fx.md?truncated=true",33594],"62ed6fb8":[()=>n.e(3089).then(n.bind(n,73418)),"@site/content/blog/2018-03-21-morphisms.md?truncated=true",73418],"636578c0":[()=>n.e(8201).then(n.bind(n,54530)),"@site/content/blog/2023-04-16-arrow-2-0-trajectory.md",54530],"6530c232":[()=>n.e(2477).then(n.bind(n,87564)),"@site/content/docs/learn/typed-errors/nullable-and-option.md",87564],"65b29259":[()=>n.e(1897).then(n.bind(n,73599)),"@site/content/blog/2018-11-30-hangman.md",73599],"65ee8c6c":[()=>Promise.all([n.e(532),n.e(4576)]).then(n.bind(n,3555)),"@site/src/pages/community/support/support.tsx",3555],"6629c45f":[()=>n.e(6919).then(n.t.bind(n,66450,19)),"@generated/docusaurus-plugin-content-docs/default/p/index.json",66450],"666004bc":[()=>n.e(7862).then(n.bind(n,85484)),"@site/content/blog/2022-05-31-building-applications-with-kotlin-and-arrow-kt-in-style.md",85484],"676c5847":[()=>n.e(3484).then(n.bind(n,76761)),"@site/content/blog/2017-09-17-handling-exceptions-arrow.md?truncated=true",76761],68297767:[()=>n.e(3005).then(n.t.bind(n,74276,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-9-ad9.json",74276],"695c6a7e":[()=>n.e(46).then(n.bind(n,35230)),"@site/content/blog/2017-11-24-building-dsl-kotlin.md",35230],"6ae227e1":[()=>n.e(8680).then(n.bind(n,62808)),"@site/content/docs/learn/typed-errors/either_ior.md",62808],"6b253531":[()=>n.e(8618).then(n.bind(n,25248)),"@site/content/blog/2023-02-04-functional-fun-kotlin.md",25248],"6ba49fad":[()=>n.e(7491).then(n.bind(n,51408)),"@site/content/docs/ecosystem/suspendapp/ktor.md",51408],"6bd16106":[()=>n.e(5717).then(n.bind(n,44149)),"@site/content/blog/2022-12-01-functional-error-handling.md?truncated=true",44149],"6c38400b":[()=>n.e(558).then(n.bind(n,70839)),"@site/content/blog/2017-11-29-fp-kotlin-arrow.md?truncated=true",70839],"6ce8e29b":[()=>n.e(9573).then(n.bind(n,67754)),"@site/content/blog/2022-05-31-building-applications-with-kotlin-and-arrow-kt-in-style.md?truncated=true",67754],"6d31d159":[()=>n.e(7453).then(n.bind(n,3646)),"@site/content/blog/2024-10-03-arrow-open-space.md?truncated=true",3646],"6ee38be5":[()=>n.e(6307).then(n.bind(n,57570)),"@site/content/blog/2020-06-11-asynchronisme-et-hexagone-en-kotlin-avec-Arrow.md",57570],"70922a87":[()=>n.e(6238).then(n.bind(n,42617)),"@site/content/blog/2019-01-03-getting-started.md?truncated=true",42617],"70c5d597":[()=>n.e(8827).then(n.bind(n,41923)),"@site/content/blog/2022-03-03-domain-model-validation-in-kotlin-part-2.md?truncated=true",41923],"70f1ce50":[()=>n.e(4298).then(n.t.bind(n,74319,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-fx-bfb.json",74319],71366787:[()=>n.e(1491).then(n.bind(n,24433)),"@site/content/blog/2019-06-07-kotliners-arrow-fx.md",24433],"71429cd6":[()=>n.e(7926).then(n.t.bind(n,7225,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-5-ad6.json",7225],"715bbc75":[()=>n.e(3637).then(n.bind(n,97924)),"@site/content/blog/2024-06-01-intellij-plugin.md?truncated=true",97924],"73c743cd":[()=>n.e(2631).then(n.bind(n,8150)),"@site/content/blog/2020-04-08-writing-compiler-plugin-with-with-arrow-meta.md",8150],"7438dad1":[()=>n.e(4064).then(n.bind(n,43243)),"@site/content/blog/2024-10-03-arrow-open-space.md",43243],74659677:[()=>n.e(2229).then(n.bind(n,56328)),"@site/content/blog/2020-04-01-explaining-arrow-android-sample.md?truncated=true",56328],74729470:[()=>n.e(8705).then(n.bind(n,75838)),"@site/content/blog/2017-11-02-fp-kotlin.md",75838],"74b50bd7":[()=>n.e(4054).then(n.bind(n,41489)),"@site/content/docs/ecosystem/analysis/mutability.md",41489],"74b914e6":[()=>n.e(7314).then(n.t.bind(n,90993,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-analysis-fdb.json",90993],"766c6dbd":[()=>n.e(785).then(n.bind(n,13859)),"@site/content/blog/2022-12-01-graceful-shutdown-structured-concurrency.md?truncated=true",13859],"7697b00a":[()=>n.e(7692).then(n.bind(n,95465)),"@site/content/blog/2021-01-22-advanced-fp-enterprise-bee-higher-kinded-types.md",95465],"7860aa9b":[()=>n.e(1391).then(n.bind(n,33302)),"@site/content/blog/2022-07-01-exploring-arrow.md",33302],"78abaa2a":[()=>n.e(9785).then(n.bind(n,45121)),"@site/content/blog/2019-07-05-testing-with-modules.md",45121],"78c55a82":[()=>n.e(3162).then(n.bind(n,61521)),"@site/content/blog/2021-04-11-your-own-custom-spring-data-repository.md?truncated=true",61521],"79896b69":[()=>n.e(8766).then(n.bind(n,71409)),"@site/content/blog/2022-02-22-domain-model-validation-in-kotlin-part-1.md",71409],"7c52af3b":[()=>n.e(8641).then(n.bind(n,69917)),"@site/content/blog/2023-04-04-arrow-1-2-0-rc-summary.md",69917],"7cdc5775":[()=>n.e(1060).then(n.bind(n,49123)),"@site/content/blog/2019-07-22-polymorphic-fx.md",49123],"7d60642f":[()=>n.e(8108).then(n.t.bind(n,54735,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-b21.json",54735],"7f8bee18":[()=>n.e(6531).then(n.bind(n,35306)),"@site/content/blog/2020-06-05-functional-domain-modeling-kotlin.md",35306],"814f3328":[()=>n.e(2535).then(n.t.bind(n,45641,19)),"~blog/default/blog-post-list-prop-default.json",45641],"8208b5e1":[()=>n.e(392).then(n.t.bind(n,1128,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-community-4e9.json",1128],"82f29da8":[()=>n.e(1199).then(n.t.bind(n,41658,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-14-71b.json",41658],"84d42235":[()=>n.e(1529).then(n.bind(n,80406)),"@site/content/blog/2021-04-01-arrow-0-12-0-0-13-1-release.md",80406],"8512a070":[()=>n.e(9296).then(n.t.bind(n,29347,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-page-5-0a2.json",29347],"8575d7bc":[()=>n.e(1464).then(n.bind(n,93470)),"@site/content/blog/2021-02-05-advanced-fp-enterprise-bee-typeclasses.md?truncated=true",93470],"86c33e95":[()=>n.e(5050).then(n.bind(n,57006)),"@site/content/blog/2023-02-04-functional-fun-kotlin.md?truncated=true",57006],"86d73d85":[()=>n.e(2367).then(n.bind(n,17073)),"@site/content/docs/learn/design/suspend-io.md",17073],"87da6537":[()=>n.e(2800).then(n.bind(n,58867)),"@site/content/blog/2019-07-02-modular-app-kotlin.md?truncated=true",58867],"880fde3e":[()=>n.e(4287).then(n.bind(n,83923)),"@site/content/blog/2022-06-28-turbocharging-kotlin-talking-kotlin.md?truncated=true",83923],"889dff8d":[()=>n.e(2824).then(n.bind(n,93824)),"@site/content/docs/learn/collections-functions/non-empty.md",93824],"8947c6c5":[()=>n.e(1721).then(n.bind(n,62748)),"@site/content/docs/learn/typed-errors/working-with-typed-errors.md",62748],"8a674012":[()=>n.e(2207).then(n.bind(n,41603)),"@site/content/docs/learn/typed-errors/from-either-to-raise.md",41603],"8c498326":[()=>n.e(6637).then(n.bind(n,6607)),"@site/content/docs/learn/quickstart/serialization.md",6607],"8e06aed5":[()=>n.e(8104).then(n.bind(n,53627)),"@site/content/docs/learn/typed-errors/validation.md",53627],"8e0e747f":[()=>Promise.all([n.e(532),n.e(6580)]).then(n.bind(n,88058)),"@site/content/docs/ecosystem/analysis/java.md",88058],"8ff4692c":[()=>n.e(4960).then(n.bind(n,69235)),"@site/content/blog/2023-07-12-arrow-1-2-0.md?truncated=true",69235],"91be326f":[()=>n.e(5990).then(n.bind(n,4090)),"@site/content/blog/2020-05-06-android-architectures-arrow-fx.md",4090],"92951bfd":[()=>n.e(1518).then(n.bind(n,66683)),"@site/content/blog/2018-10-21-polyjokes.md",66683],"93ca4f19":[()=>n.e(7964).then(n.bind(n,88533)),"@site/content/blog/2017-11-02-fp-kotlin.md?truncated=true",88533],97971232:[()=>n.e(2472).then(n.bind(n,92935)),"@site/content/blog/2020-05-06-android-architectures-arrow-fx.md?truncated=true",92935],"97d3edaa":[()=>Promise.all([n.e(532),n.e(4436)]).then(n.bind(n,90969)),"@site/content/docs/learn/resilience/index.md",90969],"99fc3110":[()=>n.e(8269).then(n.bind(n,91567)),"@site/content/blog/2020-06-05-functional-domain-modeling-kotlin.md?truncated=true",91567],"9a257fe2":[()=>n.e(7602).then(n.bind(n,77940)),"@site/content/blog/2022-05-18-functional-programming-kotlin-exploring-arrow-ties-van-de-ven.md",77940],"9c4997a0":[()=>n.e(1733).then(n.bind(n,20897)),"@site/content/blog/2019-07-22-polymorphic-fx.md?truncated=true",20897],"9c6b90c0":[()=>Promise.all([n.e(532),n.e(4081)]).then(n.bind(n,29465)),"@site/content/docs/ecosystem/analysis/index.md",29465],"9c8a6828":[()=>n.e(8442).then(n.bind(n,8521)),"@site/content/blog/2021-02-12-hands-on-arrow.md",8521],"9ca2e1cd":[()=>n.e(3585).then(n.bind(n,46642)),"@site/content/blog/2020-10-28-arrow-promoted-to-adopt.md",46642],"9cf18e85":[()=>Promise.all([n.e(532),n.e(7350)]).then(n.bind(n,31127)),"@site/content/docs/learn/coroutines/index.md",31127],"9dc415be":[()=>n.e(3352).then(n.bind(n,20110)),"@site/content/blog/2022-05-30-extending-kotlinx-serialization-functionality-arrow-meta.md?truncated=true",20110],"9dc4a5f1":[()=>Promise.all([n.e(532),n.e(9243)]).then(n.bind(n,54469)),"@site/src/pages/community/support/index.ts",54469],"9dea61d7":[()=>n.e(1988).then(n.bind(n,36027)),"@site/content/blog/2017-10-20-functional-approach.md?truncated=true",36027],"9e4087bc":[()=>n.e(3608).then(n.bind(n,63169)),"@theme/BlogArchivePage",63169],"9e4f1940":[()=>n.e(4562).then(n.t.bind(n,16191,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-page-8-cb8.json",16191],"9e8a2536":[()=>n.e(1101).then(n.bind(n,35400)),"@site/content/blog/2022-06-28-turbocharging-kotlin-talking-kotlin.md",35400],"9f60ddc2":[()=>n.e(8498).then(n.bind(n,6043)),"@site/content/blog/2018-10-21-polyjokes.md?truncated=true",6043],a015c485:[()=>Promise.all([n.e(532),n.e(6541)]).then(n.bind(n,48217)),"@site/content/docs/learn/resilience/circuitbreaker.md",48217],a02a782e:[()=>n.e(1245).then(n.bind(n,61278)),"@site/content/blog/2018-04-23-how-do-i.md?truncated=true",61278],a176ab51:[()=>n.e(3696).then(n.bind(n,83801)),"@site/content/blog/2022-12-01-actions-as-data.md?truncated=true",83801],a1cdb7ef:[()=>n.e(2104).then(n.bind(n,3955)),"@site/content/blog/2023-04-17-typed-error-handling-in-kotlin.md?truncated=true",3955],a35f1bb7:[()=>n.e(5317).then(n.bind(n,24693)),"@site/content/blog/2021-08-12-arrow-of-outrageous-error-handling.md",24693],a5463d0a:[()=>n.e(3968).then(n.t.bind(n,73887,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-33e.json",73887],a7456010:[()=>n.e(5980).then(n.t.bind(n,79365,19)),"@generated/docusaurus-plugin-content-pages/default/__plugin.json",79365],a7911d76:[()=>n.e(1057).then(n.bind(n,40299)),"@site/content/blog/2023-05-04-arrow-trajectory-kotlinconf.md?truncated=true",40299],a7b69252:[()=>n.e(2617).then(n.bind(n,25742)),"@site/content/blog/2018-07-24-arrow-fp-kotlin.md",25742],a7bd4aaa:[()=>n.e(8518).then(n.bind(n,8564)),"@theme/DocVersionRoot",8564],a8b88903:[()=>n.e(7114).then(n.t.bind(n,72962,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-page-2-85f.json",72962],a94703ab:[()=>Promise.all([n.e(532),n.e(4368)]).then(n.bind(n,4867)),"@theme/DocRoot",4867],aba21aa0:[()=>n.e(3629).then(n.t.bind(n,41765,19)),"@generated/docusaurus-plugin-content-docs/default/__plugin.json",41765],ac459f8d:[()=>n.e(388).then(n.t.bind(n,13619,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-10-e1c.json",13619],accd01c9:[()=>n.e(5951).then(n.bind(n,51653)),"@site/content/blog/2018-03-26-kotlin-arrow.md?truncated=true",51653],acecf23e:[()=>n.e(7393).then(n.t.bind(n,81838,19)),"~blog/default/blogMetadata-default.json",81838],ad15e26c:[()=>n.e(5770).then(n.bind(n,15855)),"@site/content/blog/2023-05-04-data-transformation-kotlinconf.md",15855],ad5b15f5:[()=>n.e(1436).then(n.bind(n,23055)),"@site/content/blog/2021-11-30-functional-programming-kotlin-exploring-arrow.md",23055],ad93c04a:[()=>n.e(3572).then(n.bind(n,80285)),"@site/content/blog/2023-01-03-codelytv-interview.md?truncated=true",80285],ada4fd12:[()=>Promise.all([n.e(532),n.e(457)]).then(n.bind(n,96816)),"@site/src/components/Blog/BlogTagsPostsPage",96816],af201eb8:[()=>n.e(485).then(n.bind(n,56857)),"@site/content/blog/2021-02-19-advanced-fp-enterprise-bee-state.md",56857],b04d9971:[()=>n.e(3195).then(n.bind(n,58431)),"@site/content/docs/ecosystem/analysis/types.md",58431],b0d7ab14:[()=>n.e(2153).then(n.t.bind(n,50982,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-articles-page-6-7ed.json",50982],b1a45e72:[()=>n.e(2888).then(n.bind(n,71199)),"@site/content/blog/2021-01-29-advanced-fp-enterprise-bee-kleisli.md?truncated=true",71199],b213f10b:[()=>n.e(5128).then(n.bind(n,92602)),"@site/content/blog/2018-06-22-hk-types.md",92602],b21925ed:[()=>n.e(38).then(n.bind(n,17589)),"@site/content/blog/2020-04-06-template-oriented-programming-talk.md?truncated=true",17589],b280601f:[()=>n.e(1470).then(n.bind(n,66934)),"@site/content/blog/2020-03-02-io-integration-kotlinx-coroutines.md?truncated=true",66934],b4608a72:[()=>n.e(4115).then(n.bind(n,52670)),"@site/content/blog/2020-01-14-Arrow-Comonad-Android-Compose-gameOfLife.md",52670],b4d5e9ba:[()=>n.e(4213).then(n.bind(n,94674)),"@site/content/blog/2021-01-22-advanced-fp-enterprise-bee-higher-kinded-types.md?truncated=true",94674],b73a19d0:[()=>n.e(1385).then(n.bind(n,63744)),"@site/content/blog/2020-02-26-fp-with-kotlin-arrow.md?truncated=true",63744],b7a15083:[()=>n.e(7805).then(n.bind(n,70226)),"@site/content/docs/learn/collections-functions/collectors.md",70226],b825ad5d:[()=>n.e(8637).then(n.bind(n,49775)),"@site/content/docs/ecosystem/analysis/sarif.md",49775],b8f717f9:[()=>n.e(273).then(n.bind(n,31935)),"@site/content/blog/2020-05-27-type-proofs-fp-kotlin-talk.md",31935],b9951ab2:[()=>n.e(7463).then(n.bind(n,47386)),"@site/content/docs/learn/design/receivers-flatmap.md",47386],ba72276f:[()=>n.e(2353).then(n.bind(n,85824)),"@site/content/blog/2021-02-12-hands-on-arrow.md?truncated=true",85824],bae9286f:[()=>n.e(9280).then(n.bind(n,56736)),"@site/content/docs/ecosystem/analysis/laws.md",56736],bb2ba6e0:[()=>n.e(3653).then(n.bind(n,95062)),"@site/content/blog/2020-01-14-Arrow-Comonad-Android-Compose-gameOfLife.md?truncated=true",95062],bbd92587:[()=>n.e(2417).then(n.t.bind(n,56086,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-videos-page-7-d50.json",56086],bbf502de:[()=>n.e(1377).then(n.bind(n,81381)),"@site/content/blog/2023-04-04-arrow-1-2-0-rc-summary.md?truncated=true",81381],bd30b22e:[()=>Promise.all([n.e(532),n.e(5866)]).then(n.bind(n,40740)),"@site/content/docs/learn/typed-errors/index.md",40740],bdc4ede8:[()=>n.e(2118).then(n.bind(n,67028)),"@site/content/blog/2017-11-22-happy-path.md?truncated=true",67028],beecd95f:[()=>n.e(9832).then(n.bind(n,61562)),"@site/content/blog/2018-10-05-kotlin-conf-fp-in-kotlin-with-arrow.md?truncated=true",61562],bf71a087:[()=>n.e(696).then(n.t.bind(n,33530,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-fx-page-2-12c.json",33530],c1d43ceb:[()=>Promise.all([n.e(532),n.e(1456)]).then(n.bind(n,75548)),"@site/content/docs/learn/overview.md",75548],c21440e7:[()=>n.e(600).then(n.t.bind(n,99530,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-videos-page-3-f42.json",99530],c3211ad5:[()=>n.e(568).then(n.t.bind(n,39009,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-meta-page-2-e87.json",39009],c3eb2edf:[()=>n.e(2579).then(n.bind(n,86284)),"@site/content/blog/2024-06-01-intellij-plugin.md",86284],c4390de3:[()=>n.e(2123).then(n.t.bind(n,53653,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-8-e60.json",53653],c505fd6d:[()=>Promise.all([n.e(532),n.e(4884)]).then(n.bind(n,26287)),"@site/src/pages/training/training.tsx",26287],c72579f7:[()=>n.e(1938).then(n.bind(n,96908)),"@site/content/blog/2020-01-29-monads-and-composition-with-arrow-fx.md?truncated=true",96908],c785b474:[()=>n.e(3670).then(n.bind(n,3982)),"@site/content/docs/ecosystem/analysis/control.md",3982],c87016de:[()=>n.e(2217).then(n.bind(n,70054)),"@site/content/blog/2018-06-24-arrow-101.md",70054],ca858fc0:[()=>n.e(9535).then(n.bind(n,76025)),"@site/content/blog/2020-04-01-explaining-arrow-android-sample.md",76025],cadec404:[()=>n.e(3858).then(n.bind(n,58402)),"@site/content/blog/2022-12-01-context-receivers.md?truncated=true",58402],cb323aa8:[()=>n.e(6284).then(n.bind(n,66733)),"@site/content/blog/2023-04-16-arrow-2-0-trajectory.md?truncated=true",66733],cb46c82f:[()=>n.e(4416).then(n.bind(n,1705)),"@site/content/blog/2020-11-19-fight-complexity-with-functional-programming.md",1705],cb8f4385:[()=>n.e(6753).then(n.bind(n,84189)),"@site/content/blog/2019-10-18-lambda-world-arrow-meta.md",84189],ccc49370:[()=>Promise.all([n.e(532),n.e(583),n.e(6103)]).then(n.bind(n,48247)),"@theme/BlogPostPage",48247],ce261996:[()=>n.e(2670).then(n.bind(n,9729)),"@site/content/blog/2018-11-07-simple-management-dependency.md?truncated=true",9729],cf322d13:[()=>n.e(2939).then(n.bind(n,98493)),"@site/content/blog/2017-11-17-architectures.md",98493],d06086f2:[()=>n.e(5220).then(n.bind(n,53408)),"@site/content/blog/2019-12-15-Kotlin-coroutines-with-arrow-fx.md?truncated=true",53408],d06f2b8c:[()=>n.e(5107).then(n.bind(n,95989)),"@site/content/blog/2020-01-29-monads-and-composition-with-arrow-fx.md",95989],d0ce70b2:[()=>n.e(8077).then(n.bind(n,72894)),"@site/content/blog/2019-02-10-imperative-functional-programming-arrow.md?truncated=true",72894],d1232cd5:[()=>n.e(413).then(n.bind(n,66106)),"@site/content/blog/2019-06-04-keep-87-and-typeclasses.md?truncated=true",66106],d1c796e6:[()=>n.e(4078).then(n.bind(n,86831)),"@site/content/blog/2018-03-26-kotlin-arrow.md",86831],d3b7b572:[()=>n.e(7908).then(n.bind(n,19738)),"@site/content/blog/2021-04-13-functional-domain-modeling-kotlin-validation.md?truncated=true",19738],d592e8a4:[()=>n.e(6214).then(n.bind(n,23188)),"@site/content/blog/2019-03-12-immutable-conv-1.md",23188],d5aaedfb:[()=>n.e(4615).then(n.bind(n,76959)),"@site/content/blog/2020-05-27-type-proofs-fp-kotlin-talk.md?truncated=true",76959],d66081a9:[()=>Promise.all([n.e(532),n.e(3546)]).then(n.bind(n,64150)),"@site/src/components/Blog/BlogListPage",64150],d6710148:[()=>n.e(523).then(n.bind(n,62246)),"@site/content/blog/2022-12-01-functional-flowing.md?truncated=true",62246],d68d23ab:[()=>n.e(5841).then(n.bind(n,95256)),"@site/content/blog/2020-01-29-cleaner-composition-with-monad-comprehensions-arrow-fx.md",95256],d6bdab89:[()=>n.e(5994).then(n.bind(n,96526)),"@site/content/blog/2019-08-08-kotlin-and-arrow-the-functional-way.md",96526],d70c5e74:[()=>n.e(4823).then(n.bind(n,55264)),"@site/content/blog/2022-12-01-functional-error-handling.md",55264],d8014bd8:[()=>n.e(9329).then(n.bind(n,71139)),"@site/content/blog/2020-06-16-type-proofs-fp-kotlin-talk.md?truncated=true",71139],d8195efd:[()=>n.e(3616).then(n.bind(n,33807)),"@site/content/blog/2018-06-24-state-ecosystem.md?truncated=true",33807],d82ec2e3:[()=>n.e(1712).then(n.bind(n,31367)),"@site/content/blog/2018-03-21-morphisms.md",31367],d8634816:[()=>n.e(5497).then(n.bind(n,87133)),"@site/content/blog/2022-02-02-announcing-arrow-analysis.md?truncated=true",87133],d8e90efe:[()=>n.e(3491).then(n.bind(n,22035)),"@site/content/blog/2022-12-01-functional-flowing.md",22035],d9a79d1b:[()=>n.e(5576).then(n.bind(n,19309)),"@site/content/blog/2020-10-28-technology-radar-promotes-arrow.md?truncated=true",19309],daf46283:[()=>n.e(3571).then(n.bind(n,22468)),"@site/content/blog/2018-07-24-arrow-fp-kotlin.md?truncated=true",22468],db21316c:[()=>n.e(4186).then(n.bind(n,99929)),"@site/content/blog/2019-02-03-arrow-webflux.md",99929],dbb66fc1:[()=>n.e(5703).then(n.bind(n,22418)),"@site/content/blog/2020-06-11-asynchronisme-et-hexagone-en-kotlin-avec-Arrow.md?truncated=true",22418],dde5f91b:[()=>n.e(5183).then(n.bind(n,22494)),"@site/content/blog/2018-04-14-android-functional-validation.md?truncated=true",22494],de0db763:[()=>n.e(3602).then(n.bind(n,91479)),"@site/content/blog/2019-07-05-testing-with-modules.md?truncated=true",91479],de42cc2e:[()=>n.e(7180).then(n.bind(n,40226)),"@site/content/blog/2018-11-24-ank.md",40226],e048eb9b:[()=>n.e(5995).then(n.bind(n,79116)),"@site/content/blog/2018-01-17-optics-type-classes-arrow.md",79116],e09de867:[()=>n.e(198).then(n.bind(n,51498)),"@site/content/docs/learn/resilience/intro.md",51498],e0a13225:[()=>n.e(7435).then(n.bind(n,34630)),"@site/content/docs/learn/resilience/retry-and-repeat.md",34630],e1aeeb0b:[()=>n.e(8639).then(n.bind(n,83229)),"@site/content/docs/learn/summary.md",83229],e243fde7:[()=>n.e(4149).then(n.bind(n,27195)),"@site/content/docs/learn/coroutines/resource-safety.md",27195],e262d329:[()=>n.e(9870).then(n.bind(n,96139)),"@site/content/blog/2020-10-08-writing-kotlin-compiler-plugins-talk.md",96139],e33ce170:[()=>n.e(3640).then(n.bind(n,2755)),"@site/content/docs/learn/integrations.md",2755],e3513784:[()=>n.e(260).then(n.bind(n,47825)),"@site/content/blog/2021-12-15-functional-programming-in-kotlin-with-arrow.md",47825],e3d50916:[()=>n.e(7381).then(n.bind(n,15381)),"@site/content/blog/2022-03-31-domain-model-validation-in-kotlin-part-4.md?truncated=true",15381],e41df212:[()=>n.e(2348).then(n.t.bind(n,22761,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-archive-e8c.json",22761],e4273d1e:[()=>n.e(100).then(n.bind(n,37815)),"@site/content/blog/2017-09-17-handling-exceptions-arrow.md",37815],e445020d:[()=>n.e(6731).then(n.bind(n,28743)),"@site/content/blog/2021-01-29-advanced-fp-enterprise-bee-kleisli.md",28743],e57e0b41:[()=>n.e(3825).then(n.bind(n,64802)),"@site/content/blog/2019-11-27-functional-jvm-arrow-fx-meta.md?truncated=true",64802],e645b5a6:[()=>n.e(2951).then(n.bind(n,77117)),"@site/content/blog/2021-01-20-fp-concepts-with-arrow.md?truncated=true",77117],e6b28e18:[()=>n.e(7566).then(n.bind(n,85369)),"@site/content/blog/2019-10-18-lambda-world-arrow-meta.md?truncated=true",85369],e6ebf2f5:[()=>Promise.all([n.e(532),n.e(9152)]).then(n.bind(n,0)),"@site/content/docs/learn/collections-functions/index.md",0],e6ec1063:[()=>n.e(5587).then(n.bind(n,58059)),"@site/content/blog/2018-04-23-how-do-i.md",58059],e729471a:[()=>n.e(8437).then(n.bind(n,32237)),"@site/content/blog/2021-04-11-functional-domain-modeling-kotlin.md?truncated=true",32237],e7e23f43:[()=>n.e(632).then(n.bind(n,21389)),"@site/content/blog/2020-10-28-modifying-kotlin-nested-data-classes.md",21389],e9746b95:[()=>n.e(6722).then(n.t.bind(n,59585,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-articles-page-2-bb2.json",59585],e98307e8:[()=>n.e(8881).then(n.bind(n,30039)),"@site/content/blog/2020-04-06-template-oriented-programming.md",30039],e99c5d6a:[()=>n.e(5418).then(n.bind(n,56682)),"@site/content/docs/learn/immutable-data/traversal.md",56682],ea1fa214:[()=>n.e(2588).then(n.bind(n,25836)),"@site/content/blog/2020-10-28-modifying-kotlin-nested-data-classes.md?truncated=true",25836],eb4ef685:[()=>n.e(3455).then(n.bind(n,62544)),"@site/content/docs/learn/collections-functions/utils.md",62544],ebe4fe81:[()=>n.e(5335).then(n.bind(n,56085)),"@site/content/blog/2022-12-01-context-receivers.md",56085],ec42f770:[()=>n.e(4529).then(n.t.bind(n,79660,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-page-6-58f.json",79660],ec61bf05:[()=>Promise.all([n.e(532),n.e(4531)]).then(n.bind(n,7132)),"@site/src/pages/community/events/events.tsx",7132],ed07495c:[()=>n.e(1989).then(n.bind(n,41147)),"@site/content/blog/2018-11-07-simple-management-dependency.md",41147],eda6ea71:[()=>n.e(4881).then(n.bind(n,37454)),"@site/content/blog/2022-03-31-domain-model-validation-in-kotlin-part-4.md",37454],ee6146cb:[()=>n.e(3205).then(n.bind(n,18986)),"@site/content/blog/2023-01-03-codelytv-interview.md",18986],ee8ee294:[()=>n.e(6318).then(n.bind(n,59654)),"@site/content/blog/2020-12-16-roll-your-own-computation-blocks-kotlin.md",59654],ef3f6c86:[()=>n.e(9768).then(n.t.bind(n,42256,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-videos-page-2-dfd.json",42256],ef502b28:[()=>n.e(3050).then(n.bind(n,32923)),"@site/content/blog/2022-02-02-announcing-arrow-analysis.md",32923],ef61c72e:[()=>n.e(9863).then(n.bind(n,60811)),"@site/content/docs/learn/collections-functions/recursive.md",60811],efce9c01:[()=>n.e(214).then(n.bind(n,94309)),"@site/content/blog/2020-10-08-writing-kotlin-compiler-plugins-talk.md?truncated=true",94309],effb5cc8:[()=>n.e(2890).then(n.bind(n,98706)),"@site/content/blog/2022-12-01-graceful-shutdown-structured-concurrency.md",98706],f1e8344b:[()=>n.e(5022).then(n.t.bind(n,4917,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-articles-page-3-f01.json",4917],f2060e23:[()=>n.e(4165).then(n.bind(n,31168)),"@site/content/blog/2020-02-26-safer-programming-with-arrow.md",31168],f36ebf5b:[()=>Promise.all([n.e(532),n.e(3095)]).then(n.bind(n,65019)),"@site/content/docs/learn/design/index.md",65019],f3bf4e45:[()=>n.e(313).then(n.bind(n,94805)),"@site/content/docs/learn/resilience/saga.md",94805],f3d11ff0:[()=>n.e(2791).then(n.bind(n,83746)),"@site/content/blog/2021-01-08-advanced-fp-enterprise-bee-traverse.md",83746],f4304007:[()=>n.e(2683).then(n.bind(n,83733)),"@site/content/blog/2021-12-15-functional-programming-in-kotlin-with-arrow.md?truncated=true",83733],f539d351:[()=>n.e(3917).then(n.t.bind(n,7182,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-meta-fc9.json",7182],f5633653:[()=>n.e(3303).then(n.bind(n,65422)),"@site/content/blog/2021-01-15-advanced-fp-enterprise-bee-applicatives.md",65422],f7b0cae2:[()=>n.e(5616).then(n.bind(n,75944)),"@site/content/docs/learn/design/effects-contexts.md",75944],f88d78d6:[()=>n.e(9123).then(n.bind(n,91251)),"@site/content/blog/2017-11-09-pragmatic-functionalist.md?truncated=true",91251],f920dce2:[()=>n.e(6261).then(n.bind(n,40678)),"@site/content/blog/2021-02-26-advanced-fp-enterprise-bee-shiny-things.md?truncated=true",40678],fa16e849:[()=>n.e(5569).then(n.bind(n,22816)),"@site/content/blog/2017-10-20-functional-approach.md",22816],faf32d21:[()=>n.e(8742).then(n.bind(n,95162)),"@site/content/blog/2019-04-11-introducing-arrow-playground.md?truncated=true",95162],fb544799:[()=>n.e(9035).then(n.bind(n,12155)),"@site/content/blog/2019-11-27-functional-jvm-arrow-fx-meta.md",12155],fbc6475b:[()=>n.e(3217).then(n.bind(n,98049)),"@site/content/blog/2018-06-22-hk-types.md?truncated=true",98049],fc9da458:[()=>n.e(8188).then(n.bind(n,93927)),"@site/content/blog/2019-07-02-modular-app-kotlin.md",93927],fd6df3a6:[()=>n.e(2364).then(n.t.bind(n,2574,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-fx-page-4-a50.json",2574],fe0f8968:[()=>n.e(7324).then(n.t.bind(n,11311,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-core-page-3-550.json",11311],fef250ad:[()=>n.e(7786).then(n.bind(n,44841)),"@site/content/blog/2024-02-28-arrow-1-2-3.md?truncated=true",44841],ff2eebc9:[()=>n.e(5771).then(n.t.bind(n,34794,19)),"@generated/docusaurus-plugin-content-blog/default/p/community-blog-tags-videos-page-6-a65.json",34794]};var s=n(85893);function c(e){let{error:t,retry:n,pastDelay:r}=e;return t?(0,s.jsxs)("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"},children:[(0,s.jsx)("p",{children:String(t)}),(0,s.jsx)("div",{children:(0,s.jsx)("button",{type:"button",onClick:n,children:"Retry"})})]}):r?(0,s.jsx)("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"},children:(0,s.jsx)("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb",children:(0,s.jsxs)("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2",children:[(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsxs)("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0",children:[(0,s.jsx)("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),(0,s.jsx)("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})]}),(0,s.jsx)("circle",{cx:"22",cy:"22",r:"8",children:(0,s.jsx)("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"})})]})})}):null}var l=n(99670),u=n(30226);function d(e,t){if("*"===e)return o()({loading:c,loader:()=>n.e(486).then(n.bind(n,20486)),modules:["@theme/NotFound"],webpack:()=>[20486],render(e,t){const n=e.default;return(0,s.jsx)(u.z,{value:{plugin:{name:"native",id:"default"}},children:(0,s.jsx)(n,{...t})})}});const r=a[`${e}-${t}`],d={},p=[],f=[],m=(0,l.Z)(r);return Object.entries(m).forEach((e=>{let[t,n]=e;const r=i[n];r&&(d[t]=r[0],p.push(r[1]),f.push(r[2]))})),o().Map({loading:c,loader:d,modules:p,webpack:()=>f,render(t,n){const o=JSON.parse(JSON.stringify(r));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let i=o;const s=n.split(".");s.slice(0,-1).forEach((e=>{i=i[e]})),i[s[s.length-1]]=a}));const a=o.__comp;delete o.__comp;const i=o.__context;delete o.__context;const c=o.__props;return delete o.__props,(0,s.jsx)(u.z,{value:i,children:(0,s.jsx)(a,{...o,...c,...n})})}})}const p=[{path:"/community/blog/",component:d("/community/blog/","d23"),exact:!0},{path:"/community/blog/2017/09/17/handling-exceptions-arrow/",component:d("/community/blog/2017/09/17/handling-exceptions-arrow/","3f3"),exact:!0},{path:"/community/blog/2017/10/20/functional-approach/",component:d("/community/blog/2017/10/20/functional-approach/","991"),exact:!0},{path:"/community/blog/2017/11/02/fp-kotlin/",component:d("/community/blog/2017/11/02/fp-kotlin/","0a7"),exact:!0},{path:"/community/blog/2017/11/09/pragmatic-functionalist/",component:d("/community/blog/2017/11/09/pragmatic-functionalist/","cfa"),exact:!0},{path:"/community/blog/2017/11/17/architectures/",component:d("/community/blog/2017/11/17/architectures/","4f4"),exact:!0},{path:"/community/blog/2017/11/22/happy-path/",component:d("/community/blog/2017/11/22/happy-path/","506"),exact:!0},{path:"/community/blog/2017/11/24/building-dsl-kotlin/",component:d("/community/blog/2017/11/24/building-dsl-kotlin/","cfa"),exact:!0},{path:"/community/blog/2017/11/29/fp-kotlin-arrow/",component:d("/community/blog/2017/11/29/fp-kotlin-arrow/","377"),exact:!0},{path:"/community/blog/2018/01/17/optics-type-classes-arrow/",component:d("/community/blog/2018/01/17/optics-type-classes-arrow/","632"),exact:!0},{path:"/community/blog/2018/03/21/morphisms/",component:d("/community/blog/2018/03/21/morphisms/","6f9"),exact:!0},{path:"/community/blog/2018/03/26/kotlin-arrow/",component:d("/community/blog/2018/03/26/kotlin-arrow/","9f4"),exact:!0},{path:"/community/blog/2018/04/14/android-functional-validation/",component:d("/community/blog/2018/04/14/android-functional-validation/","3d3"),exact:!0},{path:"/community/blog/2018/04/23/how-do-i/",component:d("/community/blog/2018/04/23/how-do-i/","41c"),exact:!0},{path:"/community/blog/2018/06/22/hk-types/",component:d("/community/blog/2018/06/22/hk-types/","271"),exact:!0},{path:"/community/blog/2018/06/24/arrow-101/",component:d("/community/blog/2018/06/24/arrow-101/","1c1"),exact:!0},{path:"/community/blog/2018/06/24/state-ecosystem/",component:d("/community/blog/2018/06/24/state-ecosystem/","265"),exact:!0},{path:"/community/blog/2018/06/27/fp-kotlin-arrow/",component:d("/community/blog/2018/06/27/fp-kotlin-arrow/","777"),exact:!0},{path:"/community/blog/2018/07/24/arrow-fp-kotlin/",component:d("/community/blog/2018/07/24/arrow-fp-kotlin/","0e8"),exact:!0},{path:"/community/blog/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow/",component:d("/community/blog/2018/10/05/kotlin-conf-fp-in-kotlin-with-arrow/","159"),exact:!0},{path:"/community/blog/2018/10/21/polyjokes/",component:d("/community/blog/2018/10/21/polyjokes/","92d"),exact:!0},{path:"/community/blog/2018/11/07/simple-management-dependency/",component:d("/community/blog/2018/11/07/simple-management-dependency/","d9a"),exact:!0},{path:"/community/blog/2018/11/24/ank/",component:d("/community/blog/2018/11/24/ank/","2d3"),exact:!0},{path:"/community/blog/2018/11/30/hangman/",component:d("/community/blog/2018/11/30/hangman/","22d"),exact:!0},{path:"/community/blog/2019/01/03/getting-started/",component:d("/community/blog/2019/01/03/getting-started/","9db"),exact:!0},{path:"/community/blog/2019/02/03/arrow-webflux/",component:d("/community/blog/2019/02/03/arrow-webflux/","5ce"),exact:!0},{path:"/community/blog/2019/02/10/imperative-functional-programming-arrow/",component:d("/community/blog/2019/02/10/imperative-functional-programming-arrow/","0cc"),exact:!0},{path:"/community/blog/2019/03/12/immutable-conv-1/",component:d("/community/blog/2019/03/12/immutable-conv-1/","cce"),exact:!0},{path:"/community/blog/2019/04/11/introducing-arrow-playground/",component:d("/community/blog/2019/04/11/introducing-arrow-playground/","7eb"),exact:!0},{path:"/community/blog/2019/06/04/keep-87-and-typeclasses/",component:d("/community/blog/2019/06/04/keep-87-and-typeclasses/","341"),exact:!0},{path:"/community/blog/2019/06/07/kotliners-arrow-fx/",component:d("/community/blog/2019/06/07/kotliners-arrow-fx/","ace"),exact:!0},{path:"/community/blog/2019/07/02/modular-app-kotlin/",component:d("/community/blog/2019/07/02/modular-app-kotlin/","2c2"),exact:!0},{path:"/community/blog/2019/07/05/testing-with-modules/",component:d("/community/blog/2019/07/05/testing-with-modules/","7a0"),exact:!0},{path:"/community/blog/2019/07/22/polymorphic-fx/",component:d("/community/blog/2019/07/22/polymorphic-fx/","8ee"),exact:!0},{path:"/community/blog/2019/08/08/kotlin-and-arrow-the-functional-way/",component:d("/community/blog/2019/08/08/kotlin-and-arrow-the-functional-way/","bd9"),exact:!0},{path:"/community/blog/2019/10/18/lambda-world-arrow-meta/",component:d("/community/blog/2019/10/18/lambda-world-arrow-meta/","830"),exact:!0},{path:"/community/blog/2019/11/27/functional-jvm-arrow-fx-meta/",component:d("/community/blog/2019/11/27/functional-jvm-arrow-fx-meta/","b04"),exact:!0},{path:"/community/blog/2019/12/06/kotlinconf-arrow-meta/",component:d("/community/blog/2019/12/06/kotlinconf-arrow-meta/","fa6"),exact:!0},{path:"/community/blog/2019/12/12/GOL-using-Kotlin-and-Arrow/",component:d("/community/blog/2019/12/12/GOL-using-Kotlin-and-Arrow/","9d6"),exact:!0},{path:"/community/blog/2019/12/15/Kotlin-coroutines-with-arrow-fx/",component:d("/community/blog/2019/12/15/Kotlin-coroutines-with-arrow-fx/","a96"),exact:!0},{path:"/community/blog/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife/",component:d("/community/blog/2020/01/14/Arrow-Comonad-Android-Compose-gameOfLife/","604"),exact:!0},{path:"/community/blog/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx/",component:d("/community/blog/2020/01/29/cleaner-composition-with-monad-comprehensions-arrow-fx/","b8a"),exact:!0},{path:"/community/blog/2020/01/29/monads-and-composition-with-arrow-fx/",component:d("/community/blog/2020/01/29/monads-and-composition-with-arrow-fx/","78b"),exact:!0},{path:"/community/blog/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx/",component:d("/community/blog/2020/01/29/parallel-processing-the-functional-way-with-arrow-fx/","b6e"),exact:!0},{path:"/community/blog/2020/02/26/fp-with-kotlin-arrow/",component:d("/community/blog/2020/02/26/fp-with-kotlin-arrow/","ee9"),exact:!0},{path:"/community/blog/2020/02/26/safer-programming-with-arrow/",component:d("/community/blog/2020/02/26/safer-programming-with-arrow/","f80"),exact:!0},{path:"/community/blog/2020/03/02/io-integration-kotlinx-coroutines/",component:d("/community/blog/2020/03/02/io-integration-kotlinx-coroutines/","59e"),exact:!0},{path:"/community/blog/2020/04/01/explaining-arrow-android-sample/",component:d("/community/blog/2020/04/01/explaining-arrow-android-sample/","bc7"),exact:!0},{path:"/community/blog/2020/04/06/template-oriented-programming-talk/",component:d("/community/blog/2020/04/06/template-oriented-programming-talk/","b01"),exact:!0},{path:"/community/blog/2020/04/06/template-oriented-programming/",component:d("/community/blog/2020/04/06/template-oriented-programming/","784"),exact:!0},{path:"/community/blog/2020/04/08/writing-compiler-plugin-with-with-arrow-meta/",component:d("/community/blog/2020/04/08/writing-compiler-plugin-with-with-arrow-meta/","dcb"),exact:!0},{path:"/community/blog/2020/05/06/android-architectures-arrow-fx/",component:d("/community/blog/2020/05/06/android-architectures-arrow-fx/","090"),exact:!0},{path:"/community/blog/2020/05/27/type-proofs-fp-kotlin-talk/",component:d("/community/blog/2020/05/27/type-proofs-fp-kotlin-talk/","7b5"),exact:!0},{path:"/community/blog/2020/06/05/functional-domain-modeling-kotlin/",component:d("/community/blog/2020/06/05/functional-domain-modeling-kotlin/","a5d"),exact:!0},{path:"/community/blog/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow/",component:d("/community/blog/2020/06/11/asynchronisme-et-hexagone-en-kotlin-avec-Arrow/","de3"),exact:!0},{path:"/community/blog/2020/06/16/type-proofs-fp-kotlin-talk/",component:d("/community/blog/2020/06/16/type-proofs-fp-kotlin-talk/","132"),exact:!0},{path:"/community/blog/2020/10/08/writing-kotlin-compiler-plugins-talk/",component:d("/community/blog/2020/10/08/writing-kotlin-compiler-plugins-talk/","a68"),exact:!0},{path:"/community/blog/2020/10/28/arrow-promoted-to-adopt/",component:d("/community/blog/2020/10/28/arrow-promoted-to-adopt/","662"),exact:!0},{path:"/community/blog/2020/10/28/modifying-kotlin-nested-data-classes/",component:d("/community/blog/2020/10/28/modifying-kotlin-nested-data-classes/","a2d"),exact:!0},{path:"/community/blog/2020/10/28/technology-radar-promotes-arrow/",component:d("/community/blog/2020/10/28/technology-radar-promotes-arrow/","28e"),exact:!0},{path:"/community/blog/2020/11/19/fight-complexity-with-functional-programming/",component:d("/community/blog/2020/11/19/fight-complexity-with-functional-programming/","b94"),exact:!0},{path:"/community/blog/2020/12/16/roll-your-own-computation-blocks-kotlin/",component:d("/community/blog/2020/12/16/roll-your-own-computation-blocks-kotlin/","390"),exact:!0},{path:"/community/blog/2021/01/08/advanced-fp-enterprise-bee-traverse/",component:d("/community/blog/2021/01/08/advanced-fp-enterprise-bee-traverse/","5d4"),exact:!0},{path:"/community/blog/2021/01/13/functional-android/",component:d("/community/blog/2021/01/13/functional-android/","d7e"),exact:!0},{path:"/community/blog/2021/01/15/advanced-fp-enterprise-bee-applicatives/",component:d("/community/blog/2021/01/15/advanced-fp-enterprise-bee-applicatives/","204"),exact:!0},{path:"/community/blog/2021/01/20/fp-concepts-with-arrow/",component:d("/community/blog/2021/01/20/fp-concepts-with-arrow/","f1c"),exact:!0},{path:"/community/blog/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types/",component:d("/community/blog/2021/01/22/advanced-fp-enterprise-bee-higher-kinded-types/","da6"),exact:!0},{path:"/community/blog/2021/01/29/advanced-fp-enterprise-bee-kleisli/",component:d("/community/blog/2021/01/29/advanced-fp-enterprise-bee-kleisli/","38a"),exact:!0},{path:"/community/blog/2021/02/05/advanced-fp-enterprise-bee-typeclasses/",component:d("/community/blog/2021/02/05/advanced-fp-enterprise-bee-typeclasses/","cf8"),exact:!0},{path:"/community/blog/2021/02/10/advanced-fp-enterprise-bee-optics/",component:d("/community/blog/2021/02/10/advanced-fp-enterprise-bee-optics/","32b"),exact:!0},{path:"/community/blog/2021/02/12/hands-on-arrow/",component:d("/community/blog/2021/02/12/hands-on-arrow/","447"),exact:!0},{path:"/community/blog/2021/02/19/advanced-fp-enterprise-bee-state/",component:d("/community/blog/2021/02/19/advanced-fp-enterprise-bee-state/","bec"),exact:!0},{path:"/community/blog/2021/02/26/advanced-fp-enterprise-bee-shiny-things/",component:d("/community/blog/2021/02/26/advanced-fp-enterprise-bee-shiny-things/","321"),exact:!0},{path:"/community/blog/2021/04/01/arrow-0-12-0-0-13-1-release/",component:d("/community/blog/2021/04/01/arrow-0-12-0-0-13-1-release/","21c"),exact:!0},{path:"/community/blog/2021/04/11/functional-domain-modeling-kotlin/",component:d("/community/blog/2021/04/11/functional-domain-modeling-kotlin/","982"),exact:!0},{path:"/community/blog/2021/04/11/your-own-custom-spring-data-repository/",component:d("/community/blog/2021/04/11/your-own-custom-spring-data-repository/","7b2"),exact:!0},{path:"/community/blog/2021/04/13/functional-domain-modeling-kotlin-validation/",component:d("/community/blog/2021/04/13/functional-domain-modeling-kotlin-validation/","9fd"),exact:!0},{path:"/community/blog/2021/08/12/arrow-of-outrageous-error-handling/",component:d("/community/blog/2021/08/12/arrow-of-outrageous-error-handling/","73b"),exact:!0},{path:"/community/blog/2021/11/30/functional-programming-kotlin-exploring-arrow/",component:d("/community/blog/2021/11/30/functional-programming-kotlin-exploring-arrow/","d9f"),exact:!0},{path:"/community/blog/2021/12/15/functional-programming-in-kotlin-with-arrow/",component:d("/community/blog/2021/12/15/functional-programming-in-kotlin-with-arrow/","efa"),exact:!0},{path:"/community/blog/2022/02/02/announcing-arrow-analysis/",component:d("/community/blog/2022/02/02/announcing-arrow-analysis/","a2c"),exact:!0},{path:"/community/blog/2022/02/22/domain-model-validation-in-kotlin-part-1/",component:d("/community/blog/2022/02/22/domain-model-validation-in-kotlin-part-1/","c9c"),exact:!0},{path:"/community/blog/2022/03/03/domain-model-validation-in-kotlin-part-2/",component:d("/community/blog/2022/03/03/domain-model-validation-in-kotlin-part-2/","74f"),exact:!0},{path:"/community/blog/2022/03/10/domain-model-validation-in-kotlin-part-3/",component:d("/community/blog/2022/03/10/domain-model-validation-in-kotlin-part-3/","add"),exact:!0},{path:"/community/blog/2022/03/31/domain-model-validation-in-kotlin-part-4/",component:d("/community/blog/2022/03/31/domain-model-validation-in-kotlin-part-4/","26d"),exact:!0},{path:"/community/blog/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven/",component:d("/community/blog/2022/05/18/functional-programming-kotlin-exploring-arrow-ties-van-de-ven/","de0"),exact:!0},{path:"/community/blog/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta/",component:d("/community/blog/2022/05/30/extending-kotlinx-serialization-functionality-arrow-meta/","f6a"),exact:!0},{path:"/community/blog/2022/05/30/super-charge-build-arrow-analysis/",component:d("/community/blog/2022/05/30/super-charge-build-arrow-analysis/","834"),exact:!0},{path:"/community/blog/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style/",component:d("/community/blog/2022/05/31/building-applications-with-kotlin-and-arrow-kt-in-style/","962"),exact:!0},{path:"/community/blog/2022/06/14/arrow-kotlin-dev-day/",component:d("/community/blog/2022/06/14/arrow-kotlin-dev-day/","4a6"),exact:!0},{path:"/community/blog/2022/06/28/turbocharging-kotlin-talking-kotlin/",component:d("/community/blog/2022/06/28/turbocharging-kotlin-talking-kotlin/","4ff"),exact:!0},{path:"/community/blog/2022/07/01/exploring-arrow/",component:d("/community/blog/2022/07/01/exploring-arrow/","584"),exact:!0},{path:"/community/blog/2022/12/01/actions-as-data/",component:d("/community/blog/2022/12/01/actions-as-data/","50f"),exact:!0},{path:"/community/blog/2022/12/01/context-receivers/",component:d("/community/blog/2022/12/01/context-receivers/","a2a"),exact:!0},{path:"/community/blog/2022/12/01/functional-error-handling/",component:d("/community/blog/2022/12/01/functional-error-handling/","557"),exact:!0},{path:"/community/blog/2022/12/01/functional-flowing/",component:d("/community/blog/2022/12/01/functional-flowing/","22f"),exact:!0},{path:"/community/blog/2022/12/01/graceful-shutdown-structured-concurrency/",component:d("/community/blog/2022/12/01/graceful-shutdown-structured-concurrency/","874"),exact:!0},{path:"/community/blog/2023/01/03/codelytv-interview/",component:d("/community/blog/2023/01/03/codelytv-interview/","39c"),exact:!0},{path:"/community/blog/2023/02/04/functional-fun-kotlin/",component:d("/community/blog/2023/02/04/functional-fun-kotlin/","e2f"),exact:!0},{path:"/community/blog/2023/04/04/arrow-1-2-0-rc-summary/",component:d("/community/blog/2023/04/04/arrow-1-2-0-rc-summary/","389"),exact:!0},{path:"/community/blog/2023/04/16/arrow-2-0-trajectory/",component:d("/community/blog/2023/04/16/arrow-2-0-trajectory/","ee2"),exact:!0},{path:"/community/blog/2023/04/17/typed-error-handling-in-kotlin/",component:d("/community/blog/2023/04/17/typed-error-handling-in-kotlin/","a0e"),exact:!0},{path:"/community/blog/2023/05/04/arrow-trajectory-kotlinconf/",component:d("/community/blog/2023/05/04/arrow-trajectory-kotlinconf/","0a4"),exact:!0},{path:"/community/blog/2023/05/04/data-transformation-kotlinconf/",component:d("/community/blog/2023/05/04/data-transformation-kotlinconf/","8a0"),exact:!0},{path:"/community/blog/2023/07/12/arrow-1-2-0/",component:d("/community/blog/2023/07/12/arrow-1-2-0/","e7b"),exact:!0},{path:"/community/blog/2024/02/28/arrow-1-2-3/",component:d("/community/blog/2024/02/28/arrow-1-2-3/","dd8"),exact:!0},{path:"/community/blog/2024/06/01/intellij-plugin/",component:d("/community/blog/2024/06/01/intellij-plugin/","507"),exact:!0},{path:"/community/blog/2024/10/03/arrow-open-space/",component:d("/community/blog/2024/10/03/arrow-open-space/","3fb"),exact:!0},{path:"/community/blog/archive/",component:d("/community/blog/archive/","969"),exact:!0},{path:"/community/blog/page/10/",component:d("/community/blog/page/10/","b5b"),exact:!0},{path:"/community/blog/page/11/",component:d("/community/blog/page/11/","752"),exact:!0},{path:"/community/blog/page/12/",component:d("/community/blog/page/12/","3c5"),exact:!0},{path:"/community/blog/page/13/",component:d("/community/blog/page/13/","5b9"),exact:!0},{path:"/community/blog/page/14/",component:d("/community/blog/page/14/","263"),exact:!0},{path:"/community/blog/page/2/",component:d("/community/blog/page/2/","374"),exact:!0},{path:"/community/blog/page/3/",component:d("/community/blog/page/3/","a40"),exact:!0},{path:"/community/blog/page/4/",component:d("/community/blog/page/4/","8a9"),exact:!0},{path:"/community/blog/page/5/",component:d("/community/blog/page/5/","f7e"),exact:!0},{path:"/community/blog/page/6/",component:d("/community/blog/page/6/","2af"),exact:!0},{path:"/community/blog/page/7/",component:d("/community/blog/page/7/","dac"),exact:!0},{path:"/community/blog/page/8/",component:d("/community/blog/page/8/","0c8"),exact:!0},{path:"/community/blog/page/9/",component:d("/community/blog/page/9/","7f6"),exact:!0},{path:"/community/blog/tags/",component:d("/community/blog/tags/","4db"),exact:!0},{path:"/community/blog/tags/analysis/",component:d("/community/blog/tags/analysis/","16b"),exact:!0},{path:"/community/blog/tags/articles/",component:d("/community/blog/tags/articles/","c39"),exact:!0},{path:"/community/blog/tags/articles/page/2/",component:d("/community/blog/tags/articles/page/2/","5a2"),exact:!0},{path:"/community/blog/tags/articles/page/3/",component:d("/community/blog/tags/articles/page/3/","222"),exact:!0},{path:"/community/blog/tags/articles/page/4/",component:d("/community/blog/tags/articles/page/4/","da7"),exact:!0},{path:"/community/blog/tags/articles/page/5/",component:d("/community/blog/tags/articles/page/5/","75f"),exact:!0},{path:"/community/blog/tags/articles/page/6/",component:d("/community/blog/tags/articles/page/6/","21d"),exact:!0},{path:"/community/blog/tags/community/",component:d("/community/blog/tags/community/","409"),exact:!0},{path:"/community/blog/tags/core/",component:d("/community/blog/tags/core/","318"),exact:!0},{path:"/community/blog/tags/core/page/10/",component:d("/community/blog/tags/core/page/10/","013"),exact:!0},{path:"/community/blog/tags/core/page/2/",component:d("/community/blog/tags/core/page/2/","f14"),exact:!0},{path:"/community/blog/tags/core/page/3/",component:d("/community/blog/tags/core/page/3/","db7"),exact:!0},{path:"/community/blog/tags/core/page/4/",component:d("/community/blog/tags/core/page/4/","064"),exact:!0},{path:"/community/blog/tags/core/page/5/",component:d("/community/blog/tags/core/page/5/","0b4"),exact:!0},{path:"/community/blog/tags/core/page/6/",component:d("/community/blog/tags/core/page/6/","b34"),exact:!0},{path:"/community/blog/tags/core/page/7/",component:d("/community/blog/tags/core/page/7/","a1f"),exact:!0},{path:"/community/blog/tags/core/page/8/",component:d("/community/blog/tags/core/page/8/","a43"),exact:!0},{path:"/community/blog/tags/core/page/9/",component:d("/community/blog/tags/core/page/9/","aa2"),exact:!0},{path:"/community/blog/tags/fx/",component:d("/community/blog/tags/fx/","89c"),exact:!0},{path:"/community/blog/tags/fx/page/2/",component:d("/community/blog/tags/fx/page/2/","bf7"),exact:!0},{path:"/community/blog/tags/fx/page/3/",component:d("/community/blog/tags/fx/page/3/","c37"),exact:!0},{path:"/community/blog/tags/fx/page/4/",component:d("/community/blog/tags/fx/page/4/","579"),exact:!0},{path:"/community/blog/tags/incubator/",component:d("/community/blog/tags/incubator/","db7"),exact:!0},{path:"/community/blog/tags/intellij/",component:d("/community/blog/tags/intellij/","dda"),exact:!0},{path:"/community/blog/tags/meta/",component:d("/community/blog/tags/meta/","450"),exact:!0},{path:"/community/blog/tags/meta/page/2/",component:d("/community/blog/tags/meta/page/2/","2f6"),exact:!0},{path:"/community/blog/tags/mtl/",component:d("/community/blog/tags/mtl/","813"),exact:!0},{path:"/community/blog/tags/optics/",component:d("/community/blog/tags/optics/","5d0"),exact:!0},{path:"/community/blog/tags/slidedecks/",component:d("/community/blog/tags/slidedecks/","020"),exact:!0},{path:"/community/blog/tags/tutorials/",component:d("/community/blog/tags/tutorials/","568"),exact:!0},{path:"/community/blog/tags/videos/",component:d("/community/blog/tags/videos/","99c"),exact:!0},{path:"/community/blog/tags/videos/page/2/",component:d("/community/blog/tags/videos/page/2/","9e6"),exact:!0},{path:"/community/blog/tags/videos/page/3/",component:d("/community/blog/tags/videos/page/3/","d55"),exact:!0},{path:"/community/blog/tags/videos/page/4/",component:d("/community/blog/tags/videos/page/4/","cfc"),exact:!0},{path:"/community/blog/tags/videos/page/5/",component:d("/community/blog/tags/videos/page/5/","644"),exact:!0},{path:"/community/blog/tags/videos/page/6/",component:d("/community/blog/tags/videos/page/6/","0d6"),exact:!0},{path:"/community/blog/tags/videos/page/7/",component:d("/community/blog/tags/videos/page/7/","4db"),exact:!0},{path:"/community/events/",component:d("/community/events/","b6a"),exact:!0},{path:"/community/events/events/",component:d("/community/events/events/","4eb"),exact:!0},{path:"/community/support/",component:d("/community/support/","d2d"),exact:!0},{path:"/community/support/support/",component:d("/community/support/support/","22a"),exact:!0},{path:"/libraries/",component:d("/libraries/","8a5"),exact:!0},{path:"/libraries/libraries/",component:d("/libraries/libraries/","693"),exact:!0},{path:"/search/",component:d("/search/","7cb"),exact:!0},{path:"/training/",component:d("/training/","e7f"),exact:!0},{path:"/training/training/",component:d("/training/training/","08e"),exact:!0},{path:"/",component:d("/","e5f"),exact:!0},{path:"/",component:d("/","254"),routes:[{path:"/",component:d("/","c67"),routes:[{path:"/",component:d("/","d0e"),routes:[{path:"/ecosystem/analysis/",component:d("/ecosystem/analysis/","8bd"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/analysis/conditions/",component:d("/ecosystem/analysis/conditions/","322"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/analysis/control/",component:d("/ecosystem/analysis/control/","130"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/analysis/java/",component:d("/ecosystem/analysis/java/","54d"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/analysis/laws/",component:d("/ecosystem/analysis/laws/","b29"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/analysis/mutability/",component:d("/ecosystem/analysis/mutability/","356"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/analysis/quickstart/",component:d("/ecosystem/analysis/quickstart/","453"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/analysis/sarif/",component:d("/ecosystem/analysis/sarif/","b2c"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/analysis/types/",component:d("/ecosystem/analysis/types/","19a"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/analysis/wrappers/",component:d("/ecosystem/analysis/wrappers/","837"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/suspendapp/",component:d("/ecosystem/suspendapp/","b62"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/suspendapp/kafka/",component:d("/ecosystem/suspendapp/kafka/","240"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/ecosystem/suspendapp/ktor/",component:d("/ecosystem/suspendapp/ktor/","252"),exact:!0,sidebar:"ecosystemSidebar"},{path:"/learn/collections-functions/",component:d("/learn/collections-functions/","a2c"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/collections-functions/collectors/",component:d("/learn/collections-functions/collectors/","e0d"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/collections-functions/eval/",component:d("/learn/collections-functions/eval/","8a9"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/collections-functions/memoize/",component:d("/learn/collections-functions/memoize/","1ff"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/collections-functions/non-empty/",component:d("/learn/collections-functions/non-empty/","b0c"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/collections-functions/recursive/",component:d("/learn/collections-functions/recursive/","9d3"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/collections-functions/utils/",component:d("/learn/collections-functions/utils/","7d4"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/coroutines/",component:d("/learn/coroutines/","804"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/coroutines/concurrency-primitives/",component:d("/learn/coroutines/concurrency-primitives/","ea6"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/coroutines/parallel/",component:d("/learn/coroutines/parallel/","6ad"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/coroutines/resource-safety/",component:d("/learn/coroutines/resource-safety/","bfb"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/coroutines/stm/",component:d("/learn/coroutines/stm/","17a"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/design/",component:d("/learn/design/","b3c"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/design/domain-modeling/",component:d("/learn/design/domain-modeling/","9a4"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/design/effects-contexts/",component:d("/learn/design/effects-contexts/","2ab"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/design/projects/",component:d("/learn/design/projects/","fee"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/design/receivers-flatmap/",component:d("/learn/design/receivers-flatmap/","71b"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/design/suspend-io/",component:d("/learn/design/suspend-io/","b9e"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/immutable-data/",component:d("/learn/immutable-data/","a06"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/immutable-data/intro/",component:d("/learn/immutable-data/intro/","916"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/immutable-data/lens/",component:d("/learn/immutable-data/lens/","c21"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/immutable-data/optional/",component:d("/learn/immutable-data/optional/","573"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/immutable-data/prism-iso/",component:d("/learn/immutable-data/prism-iso/","00c"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/immutable-data/reflection/",component:d("/learn/immutable-data/reflection/","547"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/immutable-data/traversal/",component:d("/learn/immutable-data/traversal/","ee8"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/integrations/",component:d("/learn/integrations/","b03"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/overview/",component:d("/learn/overview/","3db"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/quickstart/",component:d("/learn/quickstart/","b6f"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/quickstart/compose/",component:d("/learn/quickstart/compose/","552"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/quickstart/from-fp/",component:d("/learn/quickstart/from-fp/","df3"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/quickstart/migration/",component:d("/learn/quickstart/migration/","066"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/quickstart/serialization/",component:d("/learn/quickstart/serialization/","2d8"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/resilience/",component:d("/learn/resilience/","bcc"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/resilience/circuitbreaker/",component:d("/learn/resilience/circuitbreaker/","077"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/resilience/intro/",component:d("/learn/resilience/intro/","a76"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/resilience/retry-and-repeat/",component:d("/learn/resilience/retry-and-repeat/","c7f"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/resilience/saga/",component:d("/learn/resilience/saga/","71e"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/summary/",component:d("/learn/summary/","b28"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/typed-errors/",component:d("/learn/typed-errors/","668"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/typed-errors/either-and-ior/",component:d("/learn/typed-errors/either-and-ior/","bff"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/typed-errors/from-either-to-raise/",component:d("/learn/typed-errors/from-either-to-raise/","766"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/typed-errors/nullable-and-option/",component:d("/learn/typed-errors/nullable-and-option/","a95"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/typed-errors/own-error-types/",component:d("/learn/typed-errors/own-error-types/","ff4"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/typed-errors/validation/",component:d("/learn/typed-errors/validation/","c20"),exact:!0,sidebar:"learnSidebar"},{path:"/learn/typed-errors/working-with-typed-errors/",component:d("/learn/typed-errors/working-with-typed-errors/","844"),exact:!0,sidebar:"learnSidebar"}]}]}]},{path:"*",component:d("*")}]},98934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>i});var r=n(67294),o=n(85893);const a=r.createContext(!1);function i(e){let{children:t}=e;const[n,i]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{i(!0)}),[]),(0,o.jsx)(a.Provider,{value:n,children:t})}},97221:(e,t,n)=>{"use strict";var r=n(67294),o=n(20745),a=n(73727),i=n(70405),s=n(10412);const c=[n(32497),n(3310),n(18320),n(652),n(5554),n(52295)];var l=n(723),u=n(16550),d=n(18790),p=n(85893);function f(e){let{children:t}=e;return(0,p.jsx)(p.Fragment,{children:t})}var m=n(35742),h=n(52263),g=n(44996),b=n(86668),y=n(8264),v=n(94711),_=n(19727),w=n(43320),k=n(18780),x=n(90197);function S(){const{i18n:{currentLocale:e,defaultLocale:t,localeConfigs:n}}=(0,h.Z)(),r=(0,v.l)(),o=n[e].htmlLang,a=e=>e.replace("-","_");return(0,p.jsxs)(m.Z,{children:[Object.entries(n).map((e=>{let[t,{htmlLang:n}]=e;return(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:n},t)})),(0,p.jsx)("link",{rel:"alternate",href:r.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}),(0,p.jsx)("meta",{property:"og:locale",content:a(o)}),Object.values(n).filter((e=>o!==e.htmlLang)).map((e=>(0,p.jsx)("meta",{property:"og:locale:alternate",content:a(e.htmlLang)},`meta-og-${e.htmlLang}`)))]})}function C(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,h.Z)(),r=function(){const{siteConfig:{url:e,baseUrl:t,trailingSlash:n}}=(0,h.Z)(),{pathname:r}=(0,u.TH)();return e+(0,k.applyTrailingSlash)((0,g.Z)(r),{trailingSlash:n,baseUrl:t})}(),o=t?`${n}${t}`:r;return(0,p.jsxs)(m.Z,{children:[(0,p.jsx)("meta",{property:"og:url",content:o}),(0,p.jsx)("link",{rel:"canonical",href:o})]})}function E(){const{i18n:{currentLocale:e}}=(0,h.Z)(),{metadata:t,image:n}=(0,b.L)();return(0,p.jsxs)(p.Fragment,{children:[(0,p.jsxs)(m.Z,{children:[(0,p.jsx)("meta",{name:"twitter:card",content:"summary_large_image"}),(0,p.jsx)("body",{className:_.h})]}),n&&(0,p.jsx)(y.d,{image:n}),(0,p.jsx)(C,{}),(0,p.jsx)(S,{}),(0,p.jsx)(x.Z,{tag:w.HX,locale:e}),(0,p.jsx)(m.Z,{children:t.map(((e,t)=>(0,p.jsx)("meta",{...e},t)))})]})}const T=new Map;var P=n(98934),L=n(58940),j=n(20469);function O(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>o.forEach((e=>e?.()))}const N=function(e){let{children:t,location:n,previousLocation:r}=e;return(0,j.Z)((()=>{r!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,o=t.hash===n.hash,a=t.search===n.search;if(r&&o&&!a)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:r}),O("onRouteDidUpdate",{previousLocation:r,location:n}))}),[r,n]),t};function A(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(l.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class I extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=s.Z.canUseDOM?O("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=O("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),A(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return(0,p.jsx)(N,{previousLocation:this.previousLocation,location:t,children:(0,p.jsx)(u.AW,{location:t,render:()=>e})})}}const R=I,M="__docusaurus-base-url-issue-banner-container",F="__docusaurus-base-url-issue-banner",D="__docusaurus-base-url-issue-banner-suggestion-container";function B(e){return`\ndocument.addEventListener('DOMContentLoaded', function maybeInsertBanner() {\n var shouldInsert = typeof window['docusaurus'] === 'undefined';\n shouldInsert && insertBanner();\n});\n\nfunction insertBanner() {\n var bannerContainer = document.createElement('div');\n bannerContainer.id = '${M}';\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{let{route:t}=e;return!0===t.exact})))return T.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return T.set(e.pathname,t),{...e,pathname:t}}((0,u.TH)());return(0,p.jsx)(R,{location:e,children:Z})}function W(){return(0,p.jsx)(q.Z,{children:(0,p.jsx)(L.M,{children:(0,p.jsxs)(P.t,{children:[(0,p.jsxs)(f,{children:[(0,p.jsx)(U,{}),(0,p.jsx)(E,{}),(0,p.jsx)(z,{}),(0,p.jsx)(Q,{})]}),(0,p.jsx)(V,{})]})})})}var G=n(16887);const K=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const o=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;o?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var Y=n(99670);const X=new Set,J=new Set,ee=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,te={prefetch:e=>{if(!(e=>!ee()&&!J.has(e)&&!X.has(e))(e))return!1;X.add(e);const t=(0,d.f)(l.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,Y.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?K(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!ee()&&!J.has(e))(e)&&(J.add(e),A(e))},ne=Object.freeze(te),re=Boolean(!0);if(s.Z.canUseDOM){window.docusaurus=ne;const e=document.getElementById("__docusaurus"),t=(0,p.jsx)(i.B6,{children:(0,p.jsx)(a.VK,{children:(0,p.jsx)(W,{})})}),n=(e,t)=>{console.error("Docusaurus React Root onRecoverableError:",e,t)},s=()=>{if(window.docusaurusRoot)window.docusaurusRoot.render(t);else if(re)window.docusaurusRoot=o.hydrateRoot(e,t,{onRecoverableError:n});else{const r=o.createRoot(e,{onRecoverableError:n});r.render(t),window.docusaurusRoot=r}};A(window.location.pathname).then((()=>{(0,r.startTransition)(s)}))}},58940:(e,t,n)=>{"use strict";n.d(t,{_:()=>d,M:()=>p});var r=n(67294),o=n(36809);const a=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/","versions":[{"name":"current","label":"Next","isLast":true,"path":"/","mainDocId":"learn/overview","docs":[{"id":"ecosystem/analysis/conditions","path":"/ecosystem/analysis/conditions","sidebar":"ecosystemSidebar"},{"id":"ecosystem/analysis/control","path":"/ecosystem/analysis/control","sidebar":"ecosystemSidebar"},{"id":"ecosystem/analysis/index","path":"/ecosystem/analysis/","sidebar":"ecosystemSidebar"},{"id":"ecosystem/analysis/java","path":"/ecosystem/analysis/java","sidebar":"ecosystemSidebar"},{"id":"ecosystem/analysis/laws","path":"/ecosystem/analysis/laws","sidebar":"ecosystemSidebar"},{"id":"ecosystem/analysis/mutability","path":"/ecosystem/analysis/mutability","sidebar":"ecosystemSidebar"},{"id":"ecosystem/analysis/quickstart","path":"/ecosystem/analysis/quickstart","sidebar":"ecosystemSidebar"},{"id":"ecosystem/analysis/sarif","path":"/ecosystem/analysis/sarif","sidebar":"ecosystemSidebar"},{"id":"ecosystem/analysis/types","path":"/ecosystem/analysis/types","sidebar":"ecosystemSidebar"},{"id":"ecosystem/analysis/wrappers","path":"/ecosystem/analysis/wrappers","sidebar":"ecosystemSidebar"},{"id":"ecosystem/suspendapp/index","path":"/ecosystem/suspendapp/","sidebar":"ecosystemSidebar"},{"id":"ecosystem/suspendapp/kafka","path":"/ecosystem/suspendapp/kafka","sidebar":"ecosystemSidebar"},{"id":"ecosystem/suspendapp/ktor","path":"/ecosystem/suspendapp/ktor","sidebar":"ecosystemSidebar"},{"id":"learn/collections-functions/collectors","path":"/learn/collections-functions/collectors","sidebar":"learnSidebar"},{"id":"learn/collections-functions/eval","path":"/learn/collections-functions/eval","sidebar":"learnSidebar"},{"id":"learn/collections-functions/index","path":"/learn/collections-functions/","sidebar":"learnSidebar"},{"id":"learn/collections-functions/memoize","path":"/learn/collections-functions/memoize","sidebar":"learnSidebar"},{"id":"learn/collections-functions/non-empty","path":"/learn/collections-functions/non-empty","sidebar":"learnSidebar"},{"id":"learn/collections-functions/recursive","path":"/learn/collections-functions/recursive","sidebar":"learnSidebar"},{"id":"learn/collections-functions/utils","path":"/learn/collections-functions/utils","sidebar":"learnSidebar"},{"id":"learn/coroutines/concurrency-primitives","path":"/learn/coroutines/concurrency-primitives","sidebar":"learnSidebar"},{"id":"learn/coroutines/index","path":"/learn/coroutines/","sidebar":"learnSidebar"},{"id":"learn/coroutines/parallel","path":"/learn/coroutines/parallel","sidebar":"learnSidebar"},{"id":"learn/coroutines/resource-safety","path":"/learn/coroutines/resource-safety","sidebar":"learnSidebar"},{"id":"learn/coroutines/stm","path":"/learn/coroutines/stm","sidebar":"learnSidebar"},{"id":"learn/design/domain-modeling","path":"/learn/design/domain-modeling","sidebar":"learnSidebar"},{"id":"learn/design/effects-contexts","path":"/learn/design/effects-contexts","sidebar":"learnSidebar"},{"id":"learn/design/index","path":"/learn/design/","sidebar":"learnSidebar"},{"id":"learn/design/projects","path":"/learn/design/projects","sidebar":"learnSidebar"},{"id":"learn/design/receivers-flatmap","path":"/learn/design/receivers-flatmap","sidebar":"learnSidebar"},{"id":"learn/design/suspend-io","path":"/learn/design/suspend-io","sidebar":"learnSidebar"},{"id":"learn/immutable-data/index","path":"/learn/immutable-data/","sidebar":"learnSidebar"},{"id":"learn/immutable-data/intro","path":"/learn/immutable-data/intro","sidebar":"learnSidebar"},{"id":"learn/immutable-data/lens","path":"/learn/immutable-data/lens","sidebar":"learnSidebar"},{"id":"learn/immutable-data/optional","path":"/learn/immutable-data/optional","sidebar":"learnSidebar"},{"id":"learn/immutable-data/prism-iso","path":"/learn/immutable-data/prism-iso","sidebar":"learnSidebar"},{"id":"learn/immutable-data/reflection","path":"/learn/immutable-data/reflection","sidebar":"learnSidebar"},{"id":"learn/immutable-data/traversal","path":"/learn/immutable-data/traversal","sidebar":"learnSidebar"},{"id":"learn/integrations","path":"/learn/integrations","sidebar":"learnSidebar"},{"id":"learn/overview","path":"/learn/overview","sidebar":"learnSidebar"},{"id":"learn/quickstart/compose","path":"/learn/quickstart/compose","sidebar":"learnSidebar"},{"id":"learn/quickstart/from-fp","path":"/learn/quickstart/from-fp","sidebar":"learnSidebar"},{"id":"learn/quickstart/index","path":"/learn/quickstart/","sidebar":"learnSidebar"},{"id":"learn/quickstart/migration","path":"/learn/quickstart/migration","sidebar":"learnSidebar"},{"id":"learn/quickstart/serialization","path":"/learn/quickstart/serialization","sidebar":"learnSidebar"},{"id":"learn/resilience/circuitbreaker","path":"/learn/resilience/circuitbreaker","sidebar":"learnSidebar"},{"id":"learn/resilience/index","path":"/learn/resilience/","sidebar":"learnSidebar"},{"id":"learn/resilience/intro","path":"/learn/resilience/intro","sidebar":"learnSidebar"},{"id":"learn/resilience/retry-and-repeat","path":"/learn/resilience/retry-and-repeat","sidebar":"learnSidebar"},{"id":"learn/resilience/saga","path":"/learn/resilience/saga","sidebar":"learnSidebar"},{"id":"learn/summary","path":"/learn/summary","sidebar":"learnSidebar"},{"id":"learn/typed-errors/either-and-ior","path":"/learn/typed-errors/either-and-ior","sidebar":"learnSidebar"},{"id":"learn/typed-errors/from-either-to-raise","path":"/learn/typed-errors/from-either-to-raise","sidebar":"learnSidebar"},{"id":"learn/typed-errors/index","path":"/learn/typed-errors/","sidebar":"learnSidebar"},{"id":"learn/typed-errors/nullable-and-option","path":"/learn/typed-errors/nullable-and-option","sidebar":"learnSidebar"},{"id":"learn/typed-errors/own-error-types","path":"/learn/typed-errors/own-error-types","sidebar":"learnSidebar"},{"id":"learn/typed-errors/validation","path":"/learn/typed-errors/validation","sidebar":"learnSidebar"},{"id":"learn/typed-errors/working-with-typed-errors","path":"/learn/typed-errors/working-with-typed-errors","sidebar":"learnSidebar"}],"draftIds":[],"sidebars":{"learnSidebar":{"link":{"path":"/learn/overview","label":"learn/overview"}},"ecosystemSidebar":{"link":{"path":"/ecosystem/suspendapp/","label":"SuspendApp"}}}}],"breadcrumbs":false}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var s=n(57529);const c=JSON.parse('{"docusaurusVersion":"3.3.2","siteVersion":"1.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"3.3.2"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"3.3.2"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"3.3.2"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"3.3.2"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"3.3.2"},"yaml-loader-plugin":{"type":"local"},"docusaurus-custom-media":{"type":"local"},"docusaurus-theme-mermaid":{"type":"package","name":"@docusaurus/theme-mermaid","version":"3.3.2"},"@easyops-cn/docusaurus-search-local":{"type":"package","name":"@easyops-cn/docusaurus-search-local","version":"0.40.1"}}}');var l=n(85893);const u={siteConfig:o.default,siteMetadata:c,globalData:a,i18n:i,codeTranslations:s},d=r.createContext(u);function p(e){let{children:t}=e;return(0,l.jsx)(d.Provider,{value:u,children:t})}},91262:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(67294);var r=n(72389),o=n(85893);function a(e){let{children:t,fallback:n}=e;return(0,r.Z)()?(0,o.jsx)(o.Fragment,{children:t?.()}):n??null}},44763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>h});var r=n(67294),o=n(10412),a=n(35742),i=n(18780),s=n(70307),c=n(30226),l=n(85893);function u(e){let{error:t,tryAgain:n}=e;return(0,l.jsxs)("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"},children:[(0,l.jsx)("h1",{style:{fontSize:"3rem"},children:"This page crashed"}),(0,l.jsx)("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"},children:"Try again"}),(0,l.jsx)(d,{error:t})]})}function d(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,l.jsx)("p",{style:{whiteSpace:"pre-wrap"},children:n})}function p(e){let{children:t}=e;return(0,l.jsx)(c.z,{value:{plugin:{name:"docusaurus-core-error-boundary",id:"default"}},children:t})}function f(e){let{error:t,tryAgain:n}=e;return(0,l.jsx)(p,{children:(0,l.jsxs)(h,{fallback:()=>(0,l.jsx)(u,{error:t,tryAgain:n}),children:[(0,l.jsx)(a.Z,{children:(0,l.jsx)("title",{children:"Page Error"})}),(0,l.jsx)(s.Z,{children:(0,l.jsx)(u,{error:t,tryAgain:n})})]})})}const m=e=>(0,l.jsx)(f,{...e});class h extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){o.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??m)(e)}return e??null}}},10412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,o={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},35742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(67294);var r=n(70405),o=n(85893);function a(e){return(0,o.jsx)(r.ql,{...e})}},33692:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(67294),o=n(73727),a=n(18780),i=n(52263),s=n(13919),c=n(10412),l=n(28138),u=n(44996),d=n(85893);function p(e,t){let{isNavLink:n,to:p,href:f,activeClassName:m,isActive:h,"data-noBrokenLinkCheck":g,autoAddBaseUrl:b=!0,...y}=e;const{siteConfig:{trailingSlash:v,baseUrl:_}}=(0,i.Z)(),{withBaseUrl:w}=(0,u.C)(),k=(0,l.Z)(),x=(0,r.useRef)(null);(0,r.useImperativeHandle)(t,(()=>x.current));const S=p||f;const C=(0,s.Z)(S),E=S?.replace("pathname://","");let T=void 0!==E?(P=E,b&&(e=>e.startsWith("/"))(P)?w(P):P):void 0;var P;T&&C&&(T=(0,a.applyTrailingSlash)(T,{trailingSlash:v,baseUrl:_}));const L=(0,r.useRef)(!1),j=n?o.OL:o.rU,O=c.Z.canUseIntersectionObserver,N=(0,r.useRef)(),A=()=>{L.current||null==T||(window.docusaurus.preload(T),L.current=!0)};(0,r.useEffect)((()=>(!O&&C&&null!=T&&window.docusaurus.prefetch(T),()=>{O&&N.current&&N.current.disconnect()})),[N,T,O,C]);const I=T?.startsWith("#")??!1,R=!y.target||"_self"===y.target,M=!T||!C||!R||I;return g||!I&&M||k.collectLink(T),y.id&&k.collectAnchor(y.id),M?(0,d.jsx)("a",{ref:x,href:T,...S&&!C&&{target:"_blank",rel:"noopener noreferrer"},...y}):(0,d.jsx)(j,{...y,onMouseEnter:A,onTouchStart:A,innerRef:e=>{x.current=e,O&&e&&C&&(N.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),N.current.observe(e))},to:T,...n&&{isActive:h,activeClassName:m}})}const f=r.forwardRef(p)},95999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>l,I:()=>c});var r=n(67294),o=n(85893);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var i=n(57529);function s(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return i[t??n]??n??t}function c(e,t){let{message:n,id:r}=e;return a(s({message:n,id:r}),t)}function l(e){let{children:t,id:n,values:r}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const i=s({message:t,id:n});return(0,o.jsx)(o.Fragment,{children:a(i,r)})}},29935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},13919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function o(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>o,b:()=>r})},44996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>s});var r=n(67294),o=n(52263),a=n(13919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,o.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:o=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,a.b)(n))return n;if(o)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const s=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+s:s}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function s(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},28138:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});var r=n(67294);n(85893);const o=r.createContext({collectAnchor:()=>{},collectLink:()=>{}}),a=()=>(0,r.useContext)(o);function i(){return a()}},52263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294),o=n(58940);function a(){return(0,r.useContext)(o._)}},72389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294),o=n(98934);function a(){return(0,r.useContext)(o._)}},20469:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(67294);const o=n(10412).Z.canUseDOM?r.useLayoutEffect:r.useEffect},65102:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});var r=n(67294),o=n(30226);function a(){const e=r.useContext(o._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}},99670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function o(e){const t={};return function e(n,o){Object.entries(n).forEach((n=>{let[a,i]=n;const s=o?`${o}.${a}`:a;r(i)?e(i,s):t[s]=i}))}(e),t}},30226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>i});var r=n(67294),o=n(85893);const a=r.createContext(null);function i(e){let{children:t,value:n}=e;const i=r.useContext(a),s=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:i,value:n})),[i,n]);return(0,o.jsx)(a.Provider,{value:s,children:t})}},80143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>h,gA:()=>p,_r:()=>u,Jo:()=>g,zh:()=>d,yW:()=>m,gB:()=>f});var r=n(16550),o=n(52263),a=n(29935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,o.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const s=e=>e.versions.find((e=>e.isLast));function c(e,t){const n=function(e,t){const n=s(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),o=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:o,alternateDocVersions:o?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(o.id):{}}}const l={},u=()=>i("docusaurus-plugin-content-docs")??l,d=e=>{try{return function(e,t,n){void 0===t&&(t=a.m),void 0===n&&(n={});const r=i(e),o=r?.[t];if(!o&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return o}("docusaurus-plugin-content-docs",e,{failfast:!0})}catch(t){throw new Error("You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled"+("Default"===e?"":` (pluginId=${e}`),{cause:t})}};function p(e){void 0===e&&(e={});const t=u(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const o=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),a=o?{pluginId:o[0],pluginData:o[1]}:void 0;if(!a&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return a}(t,n,e)}function f(e){return d(e).versions}function m(e){const t=d(e);return s(t)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return c(t,n)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=s(e);return{latestDocSuggestion:c(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},18320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(74865),o=n.n(r);o().configure({showSpinner:!1});const a={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{o().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){o().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(42573),o=n(36809);!function(e){const{themeConfig:{prism:t}}=o.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{"php"===e&&n(96854),n(20775)(`./prism-${e}`)})),delete globalThis.Prism}(r.p1)},92503:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(67294);var r=n(90512),o=n(95999),a=n(86668),i=n(33692),s=n(28138);const c={anchorWithStickyNavbar:"anchorWithStickyNavbar_LWe7",anchorWithHideOnScrollNavbar:"anchorWithHideOnScrollNavbar_WYt5"};var l=n(85893);function u(e){let{as:t,id:n,...u}=e;const d=(0,s.Z)(),{navbar:{hideOnScroll:p}}=(0,a.L)();if("h1"===t||!n)return(0,l.jsx)(t,{...u,id:void 0});d.collectAnchor(n);const f=(0,o.I)({id:"theme.common.headingLinkTitle",message:"Direct link to {heading}",description:"Title for link to heading"},{heading:"string"==typeof u.children?u.children:n});return(0,l.jsxs)(t,{...u,className:(0,r.Z)("anchor",p?c.anchorWithHideOnScrollNavbar:c.anchorWithStickyNavbar,u.className),id:n,children:[u.children,(0,l.jsx)(i.Z,{className:"hash-link",to:`#${n}`,"aria-label":f,title:f,children:"\u200b"})]})}},39471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(67294);const r={iconExternalLink:"iconExternalLink_nPIU"};var o=n(85893);function a(e){let{width:t=13.5,height:n=13.5}=e;return(0,o.jsx)("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:r.iconExternalLink,children:(0,o.jsx)("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"})})}},70307:(e,t,n)=>{"use strict";n.d(t,{Z:()=>Ut});var r=n(67294),o=n(90512),a=n(44763),i=n(8264),s=n(16550),c=n(95999),l=n(85936),u=n(85893);const d="__docusaurus_skipToContent_fallback";function p(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function f(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&p(t)}),[]);return(0,l.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&p(e.current)})),{containerRef:e,onClick:n}}const m=(0,c.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function h(e){const t=e.children??m,{containerRef:n,onClick:r}=f();return(0,u.jsx)("div",{ref:n,role:"region","aria-label":m,children:(0,u.jsx)("a",{...e,href:`#${d}`,onClick:r,children:t})})}var g=n(35281),b=n(19727);const y={skipToContent:"skipToContent_fXgn"};function v(){return(0,u.jsx)(h,{className:y.skipToContent})}var _=n(86668),w=n(59689);function k(e){let{width:t=21,height:n=21,color:r="currentColor",strokeWidth:o=1.2,className:a,...i}=e;return(0,u.jsx)("svg",{viewBox:"0 0 15 15",width:t,height:n,...i,children:(0,u.jsx)("g",{stroke:r,strokeWidth:o,children:(0,u.jsx)("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})})})}const x={closeButton:"closeButton_CVFx"};function S(e){return(0,u.jsx)("button",{type:"button","aria-label":(0,c.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"}),...e,className:(0,o.Z)("clean-btn close",x.closeButton,e.className),children:(0,u.jsx)(k,{width:14,height:14,strokeWidth:3.1})})}const C={content:"content_knG7"};function E(e){const{announcementBar:t}=(0,_.L)(),{content:n}=t;return(0,u.jsx)("div",{...e,className:(0,o.Z)(C.content,e.className),dangerouslySetInnerHTML:{__html:n}})}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function P(){const{announcementBar:e}=(0,_.L)(),{isActive:t,close:n}=(0,w.nT)();if(!t)return null;const{backgroundColor:r,textColor:o,isCloseable:a}=e;return(0,u.jsxs)("div",{className:T.announcementBar,style:{backgroundColor:r,color:o},role:"banner",children:[a&&(0,u.jsx)("div",{className:T.announcementBarPlaceholder}),(0,u.jsx)(E,{className:T.announcementBarContent}),a&&(0,u.jsx)(S,{onClick:n,className:T.announcementBarClose})]})}var L=n(93163),j=n(12466);var O=n(902),N=n(13102);const A=r.createContext(null);function I(e){let{children:t}=e;const n=function(){const e=(0,L.e)(),t=(0,N.HY)(),[n,o]=(0,r.useState)(!1),a=null!==t.component,i=(0,O.D9)(a);return(0,r.useEffect)((()=>{a&&!i&&o(!0)}),[a,i]),(0,r.useEffect)((()=>{a?e.shown||o(!0):o(!1)}),[e.shown,a]),(0,r.useMemo)((()=>[n,o]),[n])}();return(0,u.jsx)(A.Provider,{value:n,children:t})}function R(e){if(e.component){const t=e.component;return(0,u.jsx)(t,{...e.props})}}function M(){const e=(0,r.useContext)(A);if(!e)throw new O.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,o=(0,r.useCallback)((()=>n(!1)),[n]),a=(0,N.HY)();return(0,r.useMemo)((()=>({shown:t,hide:o,content:R(a)})),[o,a,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:r}=e;const{shown:a}=M();return(0,u.jsxs)("div",{className:"navbar-sidebar",children:[t,(0,u.jsxs)("div",{className:(0,o.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":a}),children:[(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:n}),(0,u.jsx)("div",{className:"navbar-sidebar__item menu",children:r})]})]})}var D=n(92949),B=n(72389);function $(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"})})}function z(e){return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:24,height:24,...e,children:(0,u.jsx)("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"})})}const U={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:r,onChange:a}=e;const i=(0,B.Z)(),s=(0,c.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===r?(0,c.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,c.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return(0,u.jsx)("div",{className:(0,o.Z)(U.toggle,t),children:(0,u.jsxs)("button",{className:(0,o.Z)("clean-btn",U.toggleButton,!i&&U.toggleButtonDisabled,n),type:"button",onClick:()=>a("dark"===r?"light":"dark"),disabled:!i,title:s,"aria-label":s,"aria-live":"polite",children:[(0,u.jsx)($,{className:(0,o.Z)(U.toggleIcon,U.lightToggleIcon)}),(0,u.jsx)(z,{className:(0,o.Z)(U.toggleIcon,U.darkToggleIcon)})]})})}const H=r.memo(q),V={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Z(e){let{className:t}=e;const n=(0,_.L)().navbar.style,r=(0,_.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:a}=(0,D.I)();return r?null:(0,u.jsx)(H,{className:t,buttonClassName:"dark"===n?V.darkNavbarColorModeToggle:void 0,value:o,onChange:a})}var Q=n(21327);function W(){return(0,u.jsx)(Q.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function G(){const e=(0,L.e)();return(0,u.jsx)("button",{type:"button","aria-label":(0,c.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle(),children:(0,u.jsx)(k,{color:"var(--ifm-color-emphasis-600)"})})}function K(){return(0,u.jsxs)("div",{className:"navbar-sidebar__brand",children:[(0,u.jsx)(W,{}),(0,u.jsx)(Z,{className:"margin-right--md"}),(0,u.jsx)(G,{})]})}var Y=n(33692),X=n(44996),J=n(13919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(39471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:r,href:o,label:a,html:i,isDropdownLink:s,prependBaseUrlToHref:c,...l}=e;const d=(0,X.Z)(r),p=(0,X.Z)(t),f=(0,X.Z)(o,{forcePrependBaseUrl:!0}),m=a&&o&&!(0,J.Z)(o),h=i?{dangerouslySetInnerHTML:{__html:i}}:{children:(0,u.jsxs)(u.Fragment,{children:[a,m&&(0,u.jsx)(te.Z,{...s&&{width:12,height:12}})]})};return o?(0,u.jsx)(Y.Z,{href:c?f:o,...l,...h}):(0,u.jsx)(Y.Z,{to:d,isNavLink:!0,...(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(p)},...l,...h})}function re(e){let{className:t,isDropdownItem:n=!1,...r}=e;const a=(0,u.jsx)(ne,{className:(0,o.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n,...r});return n?(0,u.jsx)("li",{children:a}):a}function oe(e){let{className:t,isDropdownItem:n,...r}=e;return(0,u.jsx)("li",{className:"menu__list-item",children:(0,u.jsx)(ne,{className:(0,o.Z)("menu__link",t),...r})})}function ae(e){let{mobile:t=!1,position:n,...r}=e;const o=t?oe:re;return(0,u.jsx)(o,{...r,activeClassName:r.activeClassName??(t?"menu__link--active":"navbar__link--active")})}var ie=n(86043),se=n(48596),ce=n(52263);const le={dropdownNavbarItemMobile:"dropdownNavbarItemMobile_S0Fm"};function ue(e,t){return e.some((e=>function(e,t){return!!(0,se.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function de(e){let{items:t,position:n,className:a,onClick:i,...s}=e;const c=(0,r.useRef)(null),[l,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{c.current&&!c.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[c]),(0,u.jsxs)("div",{ref:c,className:(0,o.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":l}),children:[(0,u.jsx)(ne,{"aria-haspopup":"true","aria-expanded":l,role:"button",href:s.to?void 0:"#",className:(0,o.Z)("navbar__link",a),...s,onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!l))},children:s.children??s.label}),(0,u.jsx)("ul",{className:"dropdown__menu",children:t.map(((e,t)=>(0,r.createElement)(Qe,{isDropdownItem:!0,activeClassName:"dropdown__link--active",...e,key:t})))})]})}function pe(e){let{items:t,className:n,position:a,onClick:i,...c}=e;const l=function(){const{siteConfig:{baseUrl:e}}=(0,ce.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ue(t,l),{collapsed:p,toggleCollapsed:f,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[l,d,m]),(0,u.jsxs)("li",{className:(0,o.Z)("menu__list-item",{"menu__list-item--collapsed":p}),children:[(0,u.jsx)(ne,{role:"button",className:(0,o.Z)(le.dropdownNavbarItemMobile,"menu__link menu__link--sublist menu__link--sublist-caret",n),...c,onClick:e=>{e.preventDefault(),f()},children:c.children??c.label}),(0,u.jsx)(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:p,children:t.map(((e,t)=>(0,r.createElement)(Qe,{mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active",...e,key:t})))})]})}function fe(e){let{mobile:t=!1,...n}=e;const r=t?pe:de;return(0,u.jsx)(r,{...n})}var me=n(94711);function he(e){let{width:t=20,height:n=20,...r}=e;return(0,u.jsx)("svg",{viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0,...r,children:(0,u.jsx)("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"})})}const ge="iconLanguage_nlXk";var be=n(61029),ye=n(1728),ve=n(60373),_e=n(80143),we=n(90022),ke=n(98202),xe=n(73926),Se=n(91073),Ce=n(82539),Ee=n(10726);const Te='',Pe='',Le='',je='',Oe='',Ne='',Ae='',Ie={searchBar:"searchBar_RVTs",dropdownMenu:"dropdownMenu_qbY6",searchBarLeft:"searchBarLeft_MXDe",suggestion:"suggestion_fB_2",cursor:"cursor_eG29",hitTree:"hitTree_kk6K",hitIcon:"hitIcon_a7Zy",hitPath:"hitPath_ieM4",noResultsIcon:"noResultsIcon_EBY5",hitFooter:"hitFooter_E9YW",hitWrapper:"hitWrapper_sAK8",hitTitle:"hitTitle_vyVt",hitAction:"hitAction_NqkB",hideAction:"hideAction_vcyE",noResults:"noResults_l6Q3",searchBarContainer:"searchBarContainer_NW3z",searchBarLoadingRing:"searchBarLoadingRing_YnHq",searchClearButton:"searchClearButton_qk4g",searchIndexLoading:"searchIndexLoading_EJ1f",searchHintContainer:"searchHintContainer_Pkmr",searchHint:"searchHint_iIMx",focused:"focused_OWtg",input:"input_FOTf",hint:"hint_URu1",suggestions:"suggestions_X8XU",dataset:"dataset_QiCy",empty:"empty_eITn"};function Re(e){let{document:t,type:n,page:r,metadata:o,tokens:a,isInterOfTree:i,isLastOfTree:s}=e;const c=0===n,l=1===n,u=[];i?u.push(Ne):s&&u.push(Ae);const d=u.map((e=>`${e}`)),p=`${c?Te:l?Pe:Le}`,f=[`${(0,Ee.o)(t.t,(0,Se.m)(o,"t"),a)}`];if(!i&&!s&&be.H6){const e=r?(r.b??[]).concat(r.t).concat(t.s&&t.s!==r.t?t.s:[]):t.b;f.push(`${(0,xe.e)(e??[])}`)}else c||f.push(`${(0,Ce.C)(r.t||(t.u.startsWith("/docs/api-reference/")?"API Reference":""),a)}`);const m=`${je}`;return[...d,p,``,...f,"",m].join("")}function Me(){return`${Oe}${(0,c.I)({id:"theme.SearchBar.noResultsText",message:"No results"})}`}var Fe=n(80311),De=n(50051);async function Be(){const e=await Promise.all([n.e(8443),n.e(5525)]).then(n.t.bind(n,68443,23)),t=e.default;return t.noConflict?t.noConflict():e.noConflict&&e.noConflict(),t}const $e="_highlight";const ze=function(e){let{handleSearchBarToggle:t}=e;const n=(0,B.Z)(),{siteConfig:{baseUrl:o},i18n:{currentLocale:a}}=(0,ce.Z)(),i=(0,_e.gA)();let l=o;try{const{preferredVersion:e}=(0,ve.J)(i?.pluginId??be.gQ);e&&!e.isLast&&(l=e.path+"/")}catch(F){if(be.l9&&!(F instanceof O.i6))throw F}const d=(0,s.k6)(),p=(0,s.TH)(),f=(0,r.useRef)(null),m=(0,r.useRef)(new Map),h=(0,r.useRef)(!1),[g,b]=(0,r.useState)(!1),[y,v]=(0,r.useState)(!1),[_,w]=(0,r.useState)(""),k=(0,r.useRef)(null),x=(0,r.useRef)(""),[S,C]=(0,r.useState)("");(0,r.useEffect)((()=>{if(!Array.isArray(be.Kc))return;let e="";if(p.pathname.startsWith(l)){const t=p.pathname.substring(l.length);let n;for(const e of be.Kc){const r="string"==typeof e?e:e.path;if(t===r||t.startsWith(`${r}/`)){n=r;break}}n&&(e=n)}x.current!==e&&(m.current.delete(e),x.current=e),C(e)}),[p.pathname,l]);const E=!!be.hG&&Array.isArray(be.Kc)&&""===S,T=(0,r.useCallback)((async()=>{if(E||m.current.get(S))return;m.current.set(S,"loading"),k.current?.autocomplete.destroy(),b(!0);const[{wrappedIndexes:e,zhDictionary:t},n]=await Promise.all([(0,we.w)(l,S),Be()]);if(k.current=n(f.current,{hint:!1,autoselect:!0,openOnFocus:!0,cssClasses:{root:(0,ye.Z)(Ie.searchBar,{[Ie.searchBarLeft]:"left"===be.pu}),noPrefix:!0,dropdownMenu:Ie.dropdownMenu,input:Ie.input,hint:Ie.hint,suggestions:Ie.suggestions,suggestion:Ie.suggestion,cursor:Ie.cursor,dataset:Ie.dataset,empty:Ie.empty}},[{source:(0,ke.v)(e,t,be.qo),templates:{suggestion:Re,empty:Me,footer:e=>{let{query:t,isEmpty:n}=e;if(n&&(!S||!be.pQ))return;const r=(e=>{let{query:t,isEmpty:n}=e;const r=document.createElement("a"),i=new URLSearchParams;let s;if(i.set("q",t),S){const e=S&&Array.isArray(be.Kc)?be.Kc.find((e=>"string"==typeof e?e===S:e.path===S)):S,t=e?(0,De._)(e,a).label:S;s=be.pQ&&n?(0,c.I)({id:"theme.SearchBar.seeAllOutsideContext",message:"See results outside {context}"},{context:t}):(0,c.I)({id:"theme.SearchBar.searchInContext",message:"See all results in {context}"},{context:t})}else s=(0,c.I)({id:"theme.SearchBar.seeAll",message:"See all results"});if(!S||!Array.isArray(be.Kc)||be.pQ&&n||i.set("ctx",S),l!==o){if(!l.startsWith(o))throw new Error(`Version url '${l}' does not start with base url '${o}', this is a bug of \`@easyops-cn/docusaurus-search-local\`, please report it.`);i.set("version",l.substring(o.length))}const u=`${o}search?${i.toString()}`;return r.href=u,r.textContent=s,r.addEventListener("click",(e=>{e.ctrlKey||e.metaKey||(e.preventDefault(),k.current?.autocomplete.close(),d.push(u))})),r})({query:t,isEmpty:n}),i=document.createElement("div");return i.className=Ie.hitFooter,i.appendChild(r),i}}}]).on("autocomplete:selected",(function(e,t){let{document:{u:n,h:r},tokens:o}=t;f.current?.blur();let a=n;if(be.vc&&o.length>0){const e=new URLSearchParams;for(const t of o)e.append($e,t);a+=`?${e.toString()}`}r&&(a+=r),d.push(a)})).on("autocomplete:closed",(()=>{f.current?.blur()})),m.current.set(S,"done"),b(!1),h.current){const e=f.current;e.value&&k.current?.autocomplete.open(),e.focus()}}),[E,S,l,o,d]);(0,r.useEffect)((()=>{if(!be.vc)return;const e=n?new URLSearchParams(p.search).getAll($e):[];setTimeout((()=>{const t=document.querySelector("article");if(!t)return;const n=new be.vc(t);n.unmark(),0!==e.length&&n.mark(e),w(e.join(" ")),k.current?.autocomplete.setVal(e.join(" "))}))}),[n,p.search,p.pathname]);const[P,L]=(0,r.useState)(!1),j=(0,r.useCallback)((()=>{h.current=!0,T(),L(!0),t?.(!0)}),[t,T]),N=(0,r.useCallback)((()=>{L(!1),t?.(!1)}),[t]),A=(0,r.useCallback)((()=>{T()}),[T]),I=(0,r.useCallback)((e=>{w(e.target.value),e.target.value&&v(!0)}),[]),R=!!n&&/mac/i.test(navigator.userAgentData?.platform??navigator.platform);(0,r.useEffect)((()=>{if(!be.AY)return;const e=e=>{!(R?e.metaKey:e.ctrlKey)||"k"!==e.key&&"K"!==e.key||(e.preventDefault(),f.current?.focus(),j())};return document.addEventListener("keydown",e),()=>{document.removeEventListener("keydown",e)}}),[R,j]);const M=(0,r.useCallback)((()=>{const e=new URLSearchParams(p.search);e.delete($e);const t=e.toString(),n=p.pathname+(""!=t?`?${t}`:"")+p.hash;n!=p.pathname+p.search+p.hash&&d.push(n),w(""),k.current?.autocomplete.setVal("")}),[p.pathname,p.search,p.hash,d]);return(0,u.jsxs)("div",{className:(0,ye.Z)("navbar__search",Ie.searchBarContainer,{[Ie.searchIndexLoading]:g&&y,[Ie.focused]:P}),hidden:E,children:[(0,u.jsx)("input",{placeholder:(0,c.I)({id:"theme.SearchBar.label",message:"Search",description:"The ARIA label and placeholder for search button"}),"aria-label":"Search",className:"navbar__search-input",onMouseEnter:A,onFocus:j,onBlur:N,onChange:I,ref:f,value:_}),(0,u.jsx)(Fe.Z,{className:Ie.searchBarLoadingRing}),be.AY&&be.t_&&(""!==_?(0,u.jsx)("button",{className:Ie.searchClearButton,onClick:M,children:"\u2715"}):n&&(0,u.jsxs)("div",{className:Ie.searchHintContainer,children:[(0,u.jsx)("kbd",{className:Ie.searchHint,children:R?"\u2318":"ctrl"}),(0,u.jsx)("kbd",{className:Ie.searchHint,children:"K"})]}))]})},Ue={navbarSearchContainer:"navbarSearchContainer_Bca1"};function qe(e){let{children:t,className:n}=e;return(0,u.jsx)("div",{className:(0,o.Z)(n,Ue.navbarSearchContainer),children:t})}var He=n(53438);const Ve=e=>e.docs.find((t=>t.id===e.mainDocId));const Ze={default:ae,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:r,queryString:o="",...a}=e;const{i18n:{currentLocale:i,locales:l,localeConfigs:d}}=(0,ce.Z)(),p=(0,me.l)(),{search:f,hash:m}=(0,s.TH)(),h=[...n,...l.map((e=>{const n=`${`pathname://${p.createUrl({locale:e,fullyQualified:!1})}`}${f}${m}${o}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...r],g=t?(0,c.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return(0,u.jsx)(fe,{...a,mobile:t,label:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(he,{className:ge}),g]}),items:h})},search:function(e){let{mobile:t,className:n}=e;return t?null:(0,u.jsx)(qe,{className:n,children:(0,u.jsx)(ze,{})})},dropdown:fe,html:function(e){let{value:t,className:n,mobile:r=!1,isDropdownItem:a=!1}=e;const i=a?"li":"div";return(0,u.jsx)(i,{className:(0,o.Z)({navbar__item:!r&&!a,"menu__list-item":r},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,_e.Iw)(r),i=(0,He.vY)(t,r),s=a?.path===i?.path;return null===i||i.unlisted&&!s?null:(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>s||!!a?.sidebar&&a.sidebar===i.sidebar,label:n??i.id,to:i.path})},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:r,...o}=e;const{activeDoc:a}=(0,_e.Iw)(r),i=(0,He.oz)(t,r).link;if(!i)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return(0,u.jsx)(ae,{exact:!0,...o,isActive:()=>a?.sidebar===t,label:n??i.label,to:i.path})},docsVersion:function(e){let{label:t,to:n,docsPluginId:r,...o}=e;const a=(0,He.lO)(r)[0],i=t??a.label,s=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(a).path;return(0,u.jsx)(ae,{...o,label:i,to:s})},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:r,dropdownItemsBefore:o,dropdownItemsAfter:a,...i}=e;const{search:l,hash:d}=(0,s.TH)(),p=(0,_e.Iw)(n),f=(0,_e.gB)(n),{savePreferredVersionName:m}=(0,ve.J)(n),h=[...o,...f.map((e=>{const t=p.alternateDocVersions[e.name]??Ve(e);return{label:e.label,to:`${t.path}${l}${d}`,isActive:()=>e===p.activeVersion,onClick:()=>m(e.name)}})),...a],g=(0,He.lO)(n)[0],b=t&&h.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):g.label,y=t&&h.length>1?void 0:Ve(g).path;return h.length<=1?(0,u.jsx)(ae,{...i,mobile:t,label:b,to:y,isActive:r?()=>!1:void 0}):(0,u.jsx)(fe,{...i,mobile:t,label:b,to:y,items:h,isActive:r?()=>!1:void 0})}};function Qe(e){let{type:t,...n}=e;const r=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Ze[r];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return(0,u.jsx)(o,{...n})}function We(){const e=(0,L.e)(),t=(0,_.L)().navbar.items;return(0,u.jsx)("ul",{className:"menu__list",children:t.map(((t,n)=>(0,r.createElement)(Qe,{mobile:!0,...t,onClick:()=>e.toggle(),key:n})))})}function Ge(e){return(0,u.jsx)("button",{...e,type:"button",className:"clean-btn navbar-sidebar__back",children:(0,u.jsx)(c.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)",children:"\u2190 Back to main menu"})})}function Ke(){const e=0===(0,_.L)().navbar.items.length,t=M();return(0,u.jsxs)(u.Fragment,{children:[!e&&(0,u.jsx)(Ge,{onClick:()=>t.hide()}),t.content]})}function Ye(){const e=(0,L.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?(0,u.jsx)(F,{header:(0,u.jsx)(K,{}),primaryMenu:(0,u.jsx)(We,{}),secondaryMenu:(0,u.jsx)(Ke,{})}):null}const Xe={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function Je(e){return(0,u.jsx)("div",{role:"presentation",...e,className:(0,o.Z)("navbar-sidebar__backdrop",e.className)})}function et(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:a}}=(0,_.L)(),i=(0,L.e)(),{navbarRef:s,isNavbarVisible:d}=function(e){const[t,n]=(0,r.useState)(e),o=(0,r.useRef)(!1),a=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(a.current=e.getBoundingClientRect().height)}),[]);return(0,j.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=s?n(!1):i+l{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return o.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return(0,u.jsxs)("nav",{ref:s,"aria-label":(0,c.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,o.Z)("navbar","navbar--fixed-top",n&&[Xe.navbarHideable,!d&&Xe.navbarHidden],{"navbar--dark":"dark"===a,"navbar--primary":"primary"===a,"navbar-sidebar--show":i.shown}),children:[t,(0,u.jsx)(Je,{onClick:i.toggle}),(0,u.jsx)(Ye,{})]})}var tt=n(69690);const nt="right";function rt(e){let{width:t=30,height:n=30,className:r,...o}=e;return(0,u.jsx)("svg",{className:r,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true",...o,children:(0,u.jsx)("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"})})}function ot(){const{toggle:e,shown:t}=(0,L.e)();return(0,u.jsx)("button",{onClick:e,"aria-label":(0,c.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button",children:(0,u.jsx)(rt,{})})}const at={colorModeToggle:"colorModeToggle_DEke"};function it(e){let{items:t}=e;return(0,u.jsx)(u.Fragment,{children:t.map(((e,t)=>(0,u.jsx)(tt.QW,{onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t}),children:(0,u.jsx)(Qe,{...e})},t)))})}function st(e){let{left:t,right:n}=e;return(0,u.jsxs)("div",{className:"navbar__inner",children:[(0,u.jsx)("div",{className:"navbar__items",children:t}),(0,u.jsx)("div",{className:"navbar__items navbar__items--right",children:n})]})}function ct(){const e=(0,L.e)(),t=(0,_.L)().navbar.items,[n,r]=function(e){function t(e){return"left"===(e.position??nt)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return(0,u.jsx)(st,{left:(0,u.jsxs)(u.Fragment,{children:[!e.disabled&&(0,u.jsx)(ot,{}),(0,u.jsx)(W,{}),(0,u.jsx)(it,{items:n})]}),right:(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(it,{items:r}),(0,u.jsx)(Z,{className:at.colorModeToggle}),!o&&(0,u.jsx)(qe,{children:(0,u.jsx)(ze,{})})]})})}function lt(){return(0,u.jsx)(et,{children:(0,u.jsx)(ct,{})})}var ut=n(23220);n(73935);function dt(e){let{item:t}=e;const{to:n,href:r,label:o,prependBaseUrlToHref:a,...i}=t,s=(0,X.Z)(n),c=(0,X.Z)(r,{forcePrependBaseUrl:!0});return(0,u.jsxs)(Y.Z,{className:"footer__link-item",...r?{href:a?c:r}:{to:s},...i,children:[o,r&&!(0,J.Z)(r)&&(0,u.jsx)(te.Z,{})]})}function pt(e){let{item:t}=e;return t.html?(0,u.jsx)("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)("li",{className:"footer__item",children:(0,u.jsx)(dt,{item:t})},t.href??t.to)}function ft(e){let{column:t}=e;return(0,u.jsxs)("div",{className:"col footer__col",children:[(0,u.jsx)("div",{className:"footer__title",children:t.title}),(0,u.jsx)("ul",{className:"footer__items clean-list",children:t.items.map(((e,t)=>(0,u.jsx)(pt,{item:e},t)))})]})}function mt(e){let{columns:t}=e;return(0,u.jsx)("div",{className:"row footer__links",children:t.map(((e,t)=>(0,u.jsx)(ft,{column:e},t)))})}function ht(){return(0,u.jsx)("span",{className:"footer__link-separator",children:"\xb7"})}function gt(e){let{item:t}=e;return t.html?(0,u.jsx)("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):(0,u.jsx)(dt,{item:t})}function bt(e){let{links:t}=e;return(0,u.jsx)("div",{className:"footer__links text--center",children:(0,u.jsx)("div",{className:"footer__links",children:t.map(((e,n)=>(0,u.jsxs)(r.Fragment,{children:[(0,u.jsx)(gt,{item:e}),t.length!==n+1&&(0,u.jsx)(ht,{})]},n)))})})}function yt(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?(0,u.jsx)(mt,{columns:t}):(0,u.jsx)(bt,{links:t})}var vt=n(19965);const _t={footerLogoLink:"footerLogoLink_BH7S"};function wt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),r={light:n(t.src),dark:n(t.srcDark??t.src)};return(0,u.jsx)(vt.Z,{className:(0,o.Z)("footer__logo",t.className),alt:t.alt,sources:r,width:t.width,height:t.height,style:t.style})}function kt(e){let{logo:t}=e;return t.href?(0,u.jsx)(Y.Z,{href:t.href,className:_t.footerLogoLink,target:t.target,children:(0,u.jsx)(wt,{logo:t})}):(0,u.jsx)(wt,{logo:t})}function xt(e){let{copyright:t}=e;return(0,u.jsx)("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}const St={container:"container_y1z5",logo:"logo_cbK_"};function Ct(e){let{links:t,iconLinks:n,logo:r,copyright:o}=e;return(0,u.jsx)("footer",{className:"footer",children:(0,u.jsxs)("div",{className:`container container-fluid ${St.container}`,children:[(r||o)&&(0,u.jsxs)("div",{children:[r&&(0,u.jsx)("div",{className:`margin-bottom--sm ${St.logo}`,children:r}),(0,u.jsx)("small",{children:o})]}),t,n]})})}var Et=n(91262);const Tt="https://api.github.com/repos/arrow-kt/arrow",Pt="arrow-github-info";const Lt="link_jfzs",jt="icon_QcRC",Ot="starIcon_C390",Nt=()=>{const e=(0,B.Z)(),t=(0,X.Z)("/img/icon-social-github.svg"),n=(0,X.Z)("/img/icon-star.svg"),{githubInfo:o}=function(){const[e,t]=(0,r.useState)({});return(0,r.useEffect)((()=>{(async()=>{const e=sessionStorage.getItem(Pt);if(e){const n=JSON.parse(e);t(n)}else{const e=await fetch(Tt),n=await e.json();sessionStorage.setItem(Pt,JSON.stringify(n)),t(n)}})()}),[Tt]),{githubInfo:e}}();if(!e)return null;const a=o?.watchers;return(0,u.jsx)(u.Fragment,{children:a&&(0,u.jsxs)(Y.Z,{title:"Star us in GitHub!",href:"https://github.com/arrow-kt/arrow",className:`pills__item pills__item--active ${Lt}`,children:[(0,u.jsx)("img",{src:t,className:jt,alt:"GitHub",height:"20px",width:"20px"}),"arrow \u2022 ",a.toLocaleString(),(0,u.jsx)("img",{src:n,className:Ot,alt:"Star",height:"16px",width:"16px"})]})})},At={container:"container_dM9r",starsContainer:"starsContainer_WEfU"};function It(e){let{links:t}=e;return(0,u.jsxs)("ul",{className:`clean-list ${At.container}`,children:[t.map((e=>{let{label:t,href:n,icon:r}=e;return(0,u.jsx)("li",{children:(0,u.jsx)(Y.Z,{href:n,children:(0,u.jsx)("img",{src:(0,X.Z)(`${r}`),alt:`${t}`,title:`${t}`,height:"24px",width:"24px"})})},n)})),(0,u.jsx)("div",{className:At.starsContainer,children:(0,u.jsx)(Et.Z,{fallback:(0,u.jsx)("div",{children:"Loading..."}),children:()=>(0,u.jsx)(Nt,{})})})]})}function Rt(){const{footer:e}=(0,_.L)();if(!e)return null;const{copyright:t,links:n,logo:r,style:o}=e,[a,i]=n.reduce(((e,t)=>(e["Links"===t.title?0:1].push(t),e)),[[],[]]),s=a[0].items;return(0,u.jsxs)(u.Fragment,{children:[(0,u.jsx)(Ct,{style:o,links:i&&i.length>0&&(0,u.jsx)(yt,{links:i}),iconLinks:s&&s.length>0&&(0,u.jsx)(It,{links:s}),logo:r&&(0,u.jsx)(kt,{logo:r}),copyright:t&&(0,u.jsx)(xt,{copyright:t})}),(0,u.jsx)(ut.C,{config:{projectId:"6442ad83351c12aba70adc49",accessToken:"pk_6c67a49f78a72d32727881bc42733cbb9da115b85cc1b3d2"},theme:{primaryColor:"var(--ifm-color-primary)",botName:"Arrow AI Assistant",logo:{src:"/img/arrow-brand-icon.svg",alt:"Arrow logo"}},size:"small",shape:"square",icon:"chat"})]})}const Mt=(0,r.memo)(Rt),Ft=(0,O.Qc)([D.S,w.pl,j.OC,ve.L5,i.VC,function(e){let{children:t}=e;return(0,u.jsx)(N.n2,{children:(0,u.jsx)(L.M,{children:(0,u.jsx)(I,{children:t})})})}]);function Dt(e){let{children:t}=e;return(0,u.jsx)(Ft,{children:t})}var Bt=n(92503);function $t(e){let{error:t,tryAgain:n}=e;return(0,u.jsx)("main",{className:"container margin-vert--xl",children:(0,u.jsx)("div",{className:"row",children:(0,u.jsxs)("div",{className:"col col--6 col--offset-3",children:[(0,u.jsx)(Bt.Z,{as:"h1",className:"hero__title",children:(0,u.jsx)(c.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed",children:"This page crashed."})}),(0,u.jsx)("div",{className:"margin-vert--lg",children:(0,u.jsx)(tt.Cw,{onClick:n,className:"button button--primary shadow--lw"})}),(0,u.jsx)("hr",{}),(0,u.jsx)("div",{className:"margin-vert--md",children:(0,u.jsx)(tt.aG,{error:t})})]})})})}const zt={mainWrapper:"mainWrapper_z2l0"};function Ut(e){const{children:t,noFooter:n,wrapperClassName:r,title:s,description:c}=e;return(0,b.t)(),(0,u.jsxs)(Dt,{children:[(0,u.jsx)(i.d,{title:s,description:c}),(0,u.jsx)(v,{}),(0,u.jsx)(P,{}),(0,u.jsx)(lt,{}),(0,u.jsx)("div",{id:d,className:(0,o.Z)(g.k.wrapper.main,zt.mainWrapper,r),children:(0,u.jsx)(a.Z,{fallback:e=>(0,u.jsx)($t,{...e}),children:t})}),!n&&(0,u.jsx)(Mt,{})]})}},21327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});n(67294);var r=n(33692),o=n(44996),a=n(52263),i=n(86668),s=n(19965),c=n(85893);function l(e){let{logo:t,alt:n,imageClassName:r}=e;const a={light:(0,o.Z)(t.src),dark:(0,o.Z)(t.srcDark||t.src)},i=(0,c.jsx)(s.Z,{className:t.className,sources:a,height:t.height,width:t.width,alt:n,style:t.style});return r?(0,c.jsx)("div",{className:r,children:i}):i}function u(e){const{siteConfig:{title:t}}=(0,a.Z)(),{navbar:{title:n,logo:s}}=(0,i.L)(),{imageClassName:u,titleClassName:d,...p}=e,f=(0,o.Z)(s?.href||"/"),m=n?"":t,h=s?.alt??m;return(0,c.jsxs)(r.Z,{to:f,...p,...s?.target&&{target:s.target},children:[s&&(0,c.jsx)(l,{logo:s,alt:h,imageClassName:u}),null!=n&&(0,c.jsx)("b",{className:d,children:n})]})}},90197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});n(67294);var r=n(35742),o=n(85893);function a(e){let{locale:t,version:n,tag:a}=e;const i=t;return(0,o.jsxs)(r.Z,{children:[t&&(0,o.jsx)("meta",{name:"docusaurus_locale",content:t}),n&&(0,o.jsx)("meta",{name:"docusaurus_version",content:n}),a&&(0,o.jsx)("meta",{name:"docusaurus_tag",content:a}),i&&(0,o.jsx)("meta",{name:"docsearch:language",content:i}),n&&(0,o.jsx)("meta",{name:"docsearch:version",content:n}),a&&(0,o.jsx)("meta",{name:"docsearch:docusaurus_tag",content:a})]})}},19965:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(67294),o=n(90512),a=n(72389),i=n(92949);const s={themedComponent:"themedComponent_mlkZ","themedComponent--light":"themedComponent--light_NVdE","themedComponent--dark":"themedComponent--dark_xIcU"};var c=n(85893);function l(e){let{className:t,children:n}=e;const l=(0,a.Z)(),{colorMode:u}=(0,i.I)();return(0,c.jsx)(c.Fragment,{children:(l?"dark"===u?["dark"]:["light"]:["light","dark"]).map((e=>{const a=n({theme:e,className:(0,o.Z)(t,s.themedComponent,s[`themedComponent--${e}`])});return(0,c.jsx)(r.Fragment,{children:a},e)}))})}function u(e){const{sources:t,className:n,alt:r,...o}=e;return(0,c.jsx)(l,{className:n,children:e=>{let{theme:n,className:a}=e;return(0,c.jsx)("img",{src:t[n],alt:r,className:a,...o})}})}},86043:(e,t,n)=>{"use strict";n.d(t,{u:()=>l,z:()=>b});var r=n(67294),o=n(10412),a=n(20469),i=n(91442),s=n(85893);const c="ease-in-out";function l(e){let{initialState:t}=e;const[n,o]=(0,r.useState)(t??!1),a=(0,r.useCallback)((()=>{o((e=>!e))}),[]);return{collapsed:n,setCollapsed:o,toggleCollapsed:a}}const u={display:"none",overflow:"hidden",height:"0px"},d={display:"block",overflow:"visible",height:"auto"};function p(e,t){const n=t?u:d;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:o}=e;const a=(0,r.useRef)(!1);(0,r.useEffect)((()=>{const e=t.current;function r(){const t=e.scrollHeight,n=o?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${o?.easing??c}`,height:`${t}px`}}function s(){const t=r();e.style.transition=t.transition,e.style.height=t.height}if(!a.current)return p(e,n),void(a.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,o])}function m(e){if(!o.Z.canUseDOM)return e?u:d}function h(e){let{as:t="div",collapsed:n,children:o,animation:a,onCollapseTransitionEnd:i,className:c,disableSSRStyle:l}=e;const u=(0,r.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:a}),(0,s.jsx)(t,{ref:u,style:l?void 0:m(n),onTransitionEnd:e=>{"height"===e.propertyName&&(p(u.current,n),i?.(n))},className:c,children:o})}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,r.useState)(!t),[c,l]=(0,r.useState)(t);return(0,a.Z)((()=>{t||i(!0)}),[t]),(0,a.Z)((()=>{o&&l(t)}),[o,t]),o?(0,s.jsx)(h,{...n,collapsed:c}):null}function b(e){let{lazy:t,...n}=e;const r=t?g:h;return(0,s.jsx)(r,{...n})}},59689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>h,pl:()=>m});var r=n(67294),o=n(72389),a=n(50012),i=n(902),s=n(86668),c=n(85893);const l=(0,a.WA)("docusaurus.announcement.dismiss"),u=(0,a.WA)("docusaurus.announcement.id"),d=()=>"true"===l.get(),p=e=>l.set(String(e)),f=r.createContext(null);function m(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,s.L)(),t=(0,o.Z)(),[n,a]=(0,r.useState)((()=>!!t&&d()));(0,r.useEffect)((()=>{a(d())}),[]);const i=(0,r.useCallback)((()=>{p(!0),a(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&p(!1),!r&&d()||a(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return(0,c.jsx)(f.Provider,{value:n,children:t})}function h(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},92949:(e,t,n)=>{"use strict";n.d(t,{I:()=>b,S:()=>g});var r=n(67294),o=n(10412),a=n(902),i=n(50012),s=n(86668),c=n(85893);const l=r.createContext(void 0),u="theme",d=(0,i.WA)(u),p={light:"light",dark:"dark"},f=e=>e===p.dark?p.dark:p.light,m=e=>o.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),h=e=>{d.set(f(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,s.L)(),[o,a]=(0,r.useState)(m(e));(0,r.useEffect)((()=>{t&&d.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:o=!0}=r;t?(a(t),o&&h(t)):(a(n?window.matchMedia("(prefers-color-scheme: dark)").matches?p.dark:p.light:e),d.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(o))}),[o]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=d.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const c=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||c.current?c.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:o,setColorMode:i,get isDarkTheme(){return o===p.dark},setLightTheme(){i(p.light)},setDarkTheme(){i(p.dark)}})),[o,i])}();return(0,c.jsx)(l.Provider,{value:n,children:t})}function b(){const e=(0,r.useContext)(l);if(null==e)throw new a.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},60373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>b});var r=n(67294),o=n(80143),a=n(29935),i=n(86668),s=n(53438),c=n(902),l=n(50012),u=n(85893);const d=e=>`docs-preferred-version-${e}`,p={save:(e,t,n)=>{(0,l.WA)(d(e),{persistence:t}).set(n)},read:(e,t)=>(0,l.WA)(d(e),{persistence:t}).get(),clear:(e,t)=>{(0,l.WA)(d(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const m=r.createContext(null);function h(){const e=(0,o._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[a,s]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{s(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function o(e){const t=p.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(p.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,o(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[a,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){p.save(e,t,n),s((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=h();return(0,u.jsx)(m.Provider,{value:n,children:t})}function b(e){let{children:t}=e;return s.cE?(0,u.jsx)(g,{children:t}):(0,u.jsx)(u.Fragment,{children:t})}function y(){const e=(0,r.useContext)(m);if(!e)throw new c.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=a.m);const t=(0,o.zh)(e),[n,i]=y(),{preferredVersionName:s}=n[e];return{preferredVersion:t.versions.find((e=>e.name===s))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>l,b:()=>c});var r=n(67294),o=n(902),a=n(85893);const i=Symbol("EmptyContext"),s=r.createContext(i);function c(e){let{children:t,name:n,items:o}=e;const i=(0,r.useMemo)((()=>n&&o?{name:n,items:o}:null),[n,o]);return(0,a.jsx)(s.Provider,{value:i,children:t})}function l(){const e=(0,r.useContext)(s);if(e===i)throw new o.i6("DocsSidebarProvider");return e}},74477:(e,t,n)=>{"use strict";n.d(t,{E:()=>c,q:()=>s});var r=n(67294),o=n(902),a=n(85893);const i=r.createContext(null);function s(e){let{children:t,version:n}=e;return(0,a.jsx)(i.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(i);if(null===e)throw new o.i6("DocsVersionProvider");return e}},93163:(e,t,n)=>{"use strict";n.d(t,{M:()=>p,e:()=>f});var r=n(67294),o=n(13102),a=n(87524),i=n(91980),s=n(86668),c=n(902),l=n(85893);const u=r.createContext(void 0);function d(){const e=function(){const e=(0,o.HY)(),{items:t}=(0,s.L)().navbar;return 0===t.length&&!e.component}(),t=(0,a.i)(),n=!e&&"mobile"===t,[c,l]=(0,r.useState)(!1);(0,i.Rb)((()=>{if(c)return l(!1),!1}));const u=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:u,shown:c})),[e,n,u,c])}function p(e){let{children:t}=e;const n=d();return(0,l.jsx)(u.Provider,{value:n,children:t})}function f(){const e=r.useContext(u);if(void 0===e)throw new c.i6("NavbarMobileSidebarProvider");return e}},13102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>c,Zo:()=>l,n2:()=>s});var r=n(67294),o=n(902),a=n(85893);const i=r.createContext(null);function s(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return(0,a.jsx)(i.Provider,{value:n,children:t})}function c(){const e=(0,r.useContext)(i);if(!e)throw new o.i6("NavbarSecondaryMenuContentProvider");return e[0]}function l(e){let{component:t,props:n}=e;const a=(0,r.useContext)(i);if(!a)throw new o.i6("NavbarSecondaryMenuContentProvider");const[,s]=a,c=(0,o.Ql)(n);return(0,r.useEffect)((()=>{s({component:t,props:c})}),[s,t,c]),(0,r.useEffect)((()=>()=>s({component:null,props:null})),[s]),null}},19727:(e,t,n)=>{"use strict";n.d(t,{h:()=>o,t:()=>a});var r=n(67294);const o="navigation-with-keyboard";function a(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(o),"mousedown"===e.type&&document.body.classList.remove(o)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(o),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},87524:(e,t,n)=>{"use strict";n.d(t,{i:()=>s});var r=n(67294),o=n(10412);const a={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function s(e){let{desktopBreakpoint:t=i}=void 0===e?{}:e;const[n,s]=(0,r.useState)((()=>"ssr"));return(0,r.useEffect)((()=>{function e(){s(function(e){if(!o.Z.canUseDOM)throw new Error("getWindowSize() should only be called after React hydration");return window.innerWidth>e?a.desktop:a.mobile}(t))}return e(),window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e)}}),[t]),n}},35281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",unlistedBanner:"theme-unlisted-banner",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{blogFooterTagsRow:"theme-blog-footer-tags-row",blogFooterEditMetaRow:"theme-blog-footer-edit-meta-row"},pages:{pageFooterEditMetaRow:"theme-pages-footer-edit-meta-row"}}},91442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},53438:(e,t,n)=>{"use strict";n.d(t,{LM:()=>m,MN:()=>T,SN:()=>E,_F:()=>y,cE:()=>p,f:()=>_,jA:()=>h,lO:()=>x,oz:()=>S,s1:()=>k,vY:()=>C,xz:()=>f});var r=n(67294),o=n(16550),a=n(18790),i=n(80143),s=n(60373),c=n(74477),l=n(1116),u=n(67392),d=n(48596);const p=!!i._r;function f(e){const t=(0,c.E)();if(!e)return;const n=t.docs[e];if(!n)throw new Error(`no version doc found by id=${e}`);return n}function m(e){return"link"!==e.type||e.unlisted?"category"===e.type?function(e){if(e.href&&!e.linkUnlisted)return e.href;for(const t of e.items){const e=m(t);if(e)return e}}(e):void 0:e.href}function h(){const{pathname:e}=(0,o.TH)(),t=(0,l.V)();if(!t)throw new Error("Unexpected: cant find current sidebar in context");const n=w({sidebarItems:t.items,pathname:e,onlyCategories:!0}).slice(-1)[0];if(!n)throw new Error(`${e} is not associated with a category. useCurrentSidebarCategory() should only be used on category index pages.`);return n}const g=(e,t)=>void 0!==e&&(0,d.Mg)(e,t),b=(e,t)=>e.some((e=>y(e,t)));function y(e,t){return"link"===e.type?g(e.href,t):"category"===e.type&&(g(e.href,t)||b(e.items,t))}function v(e,t){switch(e.type){case"category":return y(e,t)||e.items.some((e=>v(e,t)));case"link":return!e.unlisted||y(e,t);default:return!0}}function _(e,t){return(0,r.useMemo)((()=>e.filter((e=>v(e,t)))),[e,t])}function w(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const o=[];return function e(t){for(const a of t)if("category"===a.type&&((0,d.Mg)(a.href,n)||e(a.items))||"link"===a.type&&(0,d.Mg)(a.href,n)){return r&&"category"!==a.type||o.unshift(a),!0}return!1}(t),o}function k(){const e=(0,l.V)(),{pathname:t}=(0,o.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?w({sidebarItems:e.items,pathname:t}):null}function x(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,s.J)(e),o=(0,i.yW)(e);return(0,r.useMemo)((()=>(0,u.j)([t,n,o].filter(Boolean))),[t,n,o])}function S(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function C(e,t){const n=x(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${(0,u.j)(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function E(e){let{route:t}=e;const n=(0,o.TH)(),r=(0,c.E)(),i=t.routes,s=i.find((e=>(0,o.LX)(n.pathname,e)));if(!s)return null;const l=s.sidebar,u=l?r.docsSidebars[l]:void 0;return{docElement:(0,a.H)(i),sidebarName:l,sidebarItems:u}}function T(e){return e.filter((e=>!("category"===e.type||"link"===e.type)||!!m(e)))}},69690:(e,t,n)=>{"use strict";n.d(t,{aG:()=>u,Ac:()=>l,Cw:()=>c,QW:()=>d});var r=n(67294),o=n(95999),a=n(18780);const i={errorBoundaryError:"errorBoundaryError_a6uf",errorBoundaryFallback:"errorBoundaryFallback_VBag"};var s=n(85893);function c(e){return(0,s.jsx)("button",{type:"button",...e,children:(0,s.jsx)(o.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error",children:"Try again"})})}function l(e){let{error:t,tryAgain:n}=e;return(0,s.jsxs)("div",{className:i.errorBoundaryFallback,children:[(0,s.jsx)("p",{children:t.message}),(0,s.jsx)(c,{onClick:n})]})}function u(e){let{error:t}=e;const n=(0,a.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return(0,s.jsx)("p",{className:i.errorBoundaryError,children:n})}class d extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}},91980:(e,t,n)=>{"use strict";n.d(t,{Rb:()=>i,_X:()=>c});var r=n(67294),o=n(16550),a=n(902);function i(e){!function(e){const t=(0,o.k6)(),n=(0,a.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}function s(e){const t=(0,o.k6)();return(0,r.useSyncExternalStore)(t.listen,(()=>e(t)),(()=>e(t)))}function c(e){return s((t=>null===e?null:new URLSearchParams(t.location.search).get(e)))}},67392:(e,t,n)=>{"use strict";function r(e,t){return void 0===t&&(t=(e,t)=>e===t),e.filter(((n,r)=>e.findIndex((e=>t(e,n)))!==r))}function o(e){return Array.from(new Set(e))}n.d(t,{j:()=>o,l:()=>r})},8264:(e,t,n)=>{"use strict";n.d(t,{FG:()=>p,d:()=>u,VC:()=>f});var r=n(67294),o=n(90512),a=n(35742),i=n(65102),s=n(44996),c=n(52263);var l=n(85893);function u(e){let{title:t,description:n,keywords:r,image:o,children:i}=e;const u=function(e){const{siteConfig:t}=(0,c.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.C)(),p=o?d(o,{absolute:!0}):void 0;return(0,l.jsxs)(a.Z,{children:[t&&(0,l.jsx)("title",{children:u}),t&&(0,l.jsx)("meta",{property:"og:title",content:u}),n&&(0,l.jsx)("meta",{name:"description",content:n}),n&&(0,l.jsx)("meta",{property:"og:description",content:n}),r&&(0,l.jsx)("meta",{name:"keywords",content:Array.isArray(r)?r.join(","):r}),p&&(0,l.jsx)("meta",{property:"og:image",content:p}),p&&(0,l.jsx)("meta",{name:"twitter:image",content:p}),i]})}const d=r.createContext(void 0);function p(e){let{className:t,children:n}=e;const i=r.useContext(d),s=(0,o.Z)(i,t);return(0,l.jsxs)(d.Provider,{value:s,children:[(0,l.jsx)(a.Z,{children:(0,l.jsx)("html",{className:s})}),n]})}function f(e){let{children:t}=e;const n=(0,i.Z)(),r=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const a=`plugin-id-${n.plugin.id}`;return(0,l.jsx)(p,{className:(0,o.Z)(r,a),children:t})}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>s,Qc:()=>u,Ql:()=>l,i6:()=>c,zX:()=>i});var r=n(67294),o=n(20469),a=n(85893);function i(e){const t=(0,r.useRef)(e);return(0,o.Z)((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function s(e){const t=(0,r.useRef)();return(0,o.Z)((()=>{t.current=e})),t.current}class c extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function l(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return(0,a.jsx)(a.Fragment,{children:e.reduceRight(((e,t)=>(0,a.jsx)(t,{children:e})),n)})}}},48596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>s});var r=n(67294),o=n(723),a=n(52263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function s(){const{baseUrl:e}=(0,a.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function o(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(o).flatMap((e=>e.routes??[])))}(n)}({routes:o.Z,baseUrl:e})),[e])}},12466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>h,OC:()=>u,RF:()=>f,o5:()=>m});var r=n(67294),o=n(10412),a=n(72389),i=n(20469),s=n(902),c=n(85893);const l=r.createContext(void 0);function u(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return(0,c.jsx)(l.Provider,{value:n,children:t})}function d(){const e=(0,r.useContext)(l);if(null==e)throw new s.i6("ScrollControllerProvider");return e}const p=()=>o.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function f(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=d(),o=(0,r.useRef)(p()),a=(0,s.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=p();a(e,o.current),o.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[a,n,...t])}function m(){const e=d(),t=function(){const e=(0,r.useRef)({elem:null,top:0}),t=(0,r.useCallback)((t=>{e.current={elem:t,top:t.getBoundingClientRect().top}}),[]),n=(0,r.useCallback)((()=>{const{current:{elem:t,top:n}}=e;if(!t)return{restored:!1};const r=t.getBoundingClientRect().top-n;return r&&window.scrollBy({left:0,top:r}),e.current={elem:null,top:0},{restored:0!==r}}),[]);return(0,r.useMemo)((()=>({save:t,restore:n})),[n,t])}(),n=(0,r.useRef)(void 0),o=(0,r.useCallback)((r=>{t.save(r),e.disableScrollEvents(),n.current=()=>{const{restored:r}=t.restore();if(n.current=void 0,r){const t=()=>{e.enableScrollEvents(),window.removeEventListener("scroll",t)};window.addEventListener("scroll",t)}else e.enableScrollEvents()}}),[e,t]);return(0,i.Z)((()=>{queueMicrotask((()=>n.current?.()))})),{blockElementScrollPositionUntilNextRender:o}}function h(){const e=(0,r.useRef)(null),t=(0,a.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const o=document.documentElement.scrollTop;(n&&o>e||!n&&ot&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},43320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>o});n(52263);const r="default";function o(e,t){return`docs-${e}-${t}`}},50012:(e,t,n)=>{"use strict";n.d(t,{Nk:()=>u,WA:()=>l});var r=n(67294);const o="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:o}=e;if(n===r)return;const a=document.createEvent("StorageEvent");a.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,o),window.dispatchEvent(a)}function i(e){if(void 0===e&&(e=o),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,s||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),s=!0),null}var t}let s=!1;const c={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function l(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=i(t?.persistence);return null===n?c:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}function u(e,t){const n=(0,r.useRef)((()=>null===e?c:l(e,t))).current(),o=(0,r.useCallback)((e=>"undefined"==typeof window?()=>{}:n.listen(e)),[n]);return[(0,r.useSyncExternalStore)(o,(()=>"undefined"==typeof window?null:n.get()),(()=>null)),n]}},94711:(e,t,n)=>{"use strict";n.d(t,{l:()=>i});var r=n(52263),o=n(16550),a=n(18780);function i(){const{siteConfig:{baseUrl:e,url:t,trailingSlash:n},i18n:{defaultLocale:i,currentLocale:s}}=(0,r.Z)(),{pathname:c}=(0,o.TH)(),l=(0,a.applyTrailingSlash)(c,{trailingSlash:n,baseUrl:e}),u=s===i?e:e.replace(`/${s}/`,"/"),d=l.replace(e,"");return{createUrl:function(e){let{locale:n,fullyQualified:r}=e;return`${r?t:""}${function(e){return e===i?`${u}`:`${u}${e}/`}(n)}${d}`}}}},85936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(67294),o=n(16550),a=n(902);function i(e){const t=(0,o.TH)(),n=(0,a.D9)(t),i=(0,a.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},86668:(e,t,n)=>{"use strict";n.d(t,{L:()=>o});var r=n(52263);function o(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.removeTrailingSlash=t.addLeadingSlash=t.addTrailingSlash=void 0;const r=n(55913);function o(e){return e.endsWith("/")?e:`${e}/`}function a(e){return(0,r.removeSuffix)(e,"/")}t.addTrailingSlash=o,t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[i]=e.split(/[#?]/),s="/"===i||i===r?i:(c=i,n?o(c):a(c));var c;return e.replace(i,s)},t.addLeadingSlash=function(e){return(0,r.addPrefix)(e,"/")},t.removeTrailingSlash=a},54143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},18780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.removePrefix=t.addSuffix=t.removeSuffix=t.addPrefix=t.removeTrailingSlash=t.addLeadingSlash=t.addTrailingSlash=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var o=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(o).default}}),Object.defineProperty(t,"addTrailingSlash",{enumerable:!0,get:function(){return o.addTrailingSlash}}),Object.defineProperty(t,"addLeadingSlash",{enumerable:!0,get:function(){return o.addLeadingSlash}}),Object.defineProperty(t,"removeTrailingSlash",{enumerable:!0,get:function(){return o.removeTrailingSlash}});var a=n(55913);Object.defineProperty(t,"addPrefix",{enumerable:!0,get:function(){return a.addPrefix}}),Object.defineProperty(t,"removeSuffix",{enumerable:!0,get:function(){return a.removeSuffix}}),Object.defineProperty(t,"addSuffix",{enumerable:!0,get:function(){return a.addSuffix}}),Object.defineProperty(t,"removePrefix",{enumerable:!0,get:function(){return a.removePrefix}});var i=n(54143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return i.getErrorCausalChain}})},55913:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.removePrefix=t.addSuffix=t.removeSuffix=t.addPrefix=void 0,t.addPrefix=function(e,t){return e.startsWith(t)?e:`${t}${e}`},t.removeSuffix=function(e,t){return""===t?e:e.endsWith(t)?e.slice(0,-t.length):e},t.addSuffix=function(e,t){return e.endsWith(t)?e:`${e}${t}`},t.removePrefix=function(e,t){return e.startsWith(t)?e.slice(t.length):e}},80311:(e,t,n)=>{"use strict";n.d(t,{Z:()=>i});n(67294);var r=n(1728);const o={loadingRing:"loadingRing_RJI3","loading-ring":"loading-ring_FB5o"};var a=n(85893);function i(e){let{className:t}=e;return(0,a.jsxs)("div",{className:(0,r.Z)(o.loadingRing,t),children:[(0,a.jsx)("div",{}),(0,a.jsx)("div",{}),(0,a.jsx)("div",{}),(0,a.jsx)("div",{})]})}},90022:(e,t,n)=>{"use strict";n.d(t,{w:()=>s});var r=n(31336),o=n.n(r),a=n(61029);const i=new Map;function s(e,t){const n=`${e}${t}`;let r=i.get(n);return r||(r=async function(e,t){{const n=`${e}${a.J.replace("{dir}",t?`-${t.replace(/\//g,"-")}`:"")}`;if(new URL(n,location.origin).origin!==location.origin)throw new Error("Unexpected version url");const r=await(await fetch(n)).json(),i=r.map(((e,t)=>{let{documents:n,index:r}=e;return{type:t,documents:n,index:o().Index.load(r)}})),s=r.reduce(((e,t)=>{for(const n of t.index.invertedIndex)/\p{Unified_Ideograph}/u.test(n[0][0])&&e.add(n[0]);return e}),new Set);return{wrappedIndexes:i,zhDictionary:Array.from(s)}}return{wrappedIndexes:[],zhDictionary:[]}}(e,t),i.set(n,r)),r}},98202:(e,t,n)=>{"use strict";n.d(t,{v:()=>c});var r=n(31336),o=n.n(r);var a=n(61029);function i(e){return s(e).concat(s(e.filter((e=>{const t=e[e.length-1];return!t.trailing&&t.maybeTyping})),!0))}function s(e,t){return e.map((e=>({tokens:e.map((e=>e.value)),term:e.map((e=>({value:e.value,presence:o().Query.presence.REQUIRED,wildcard:(t?e.trailing||e.maybeTyping:e.trailing)?o().Query.wildcard.TRAILING:o().Query.wildcard.NONE})))})))}function c(e,t,n){return function(r,s){const c=function(e,t){if(1===t.length&&["ja","jp","th"].includes(t[0]))return o()[t[0]].tokenizer(e).map((e=>e.toString()));let n=/[^-\s]+/g;return t.includes("zh")&&(n=/\w+|\p{Unified_Ideograph}+/gu),e.toLowerCase().match(n)||[]}(r,a.dK);if(0===c.length)return void s([]);const l=function(e,t){const n=function(e,t){const n=[];return function e(r,o){if(0===r.length)return void n.push(o);const a=r[0];if(/\p{Unified_Ideograph}/u.test(a)){const n=function(e,t){const n=[];return function e(r,o){let a=0,i=!1;for(const s of t)if(r.substr(0,s.length)===s){const t={missed:o.missed,term:o.term.concat({value:s})};r.length>s.length?e(r.substr(s.length),t):n.push(t),i=!0}else for(let t=s.length-1;t>a;t-=1){const c=s.substr(0,t);if(r.substr(0,t)===c){a=t;const s={missed:o.missed,term:o.term.concat({value:c,trailing:!0})};r.length>t?e(r.substr(t),s):n.push(s),i=!0;break}}i||(r.length>0?e(r.substr(1),{missed:o.missed+1,term:o.term}):o.term.length>0&&n.push(o))}(e,{missed:0,term:[]}),n.sort(((e,t)=>{const n=e.missed>0?1:0,r=t.missed>0?1:0;return n!==r?n-r:e.term.length-t.term.length})).map((e=>e.term))}(a,t);for(const t of n){const n=o.concat(...t);e(r.slice(1),n)}}else{const t=o.concat({value:a});e(r.slice(1),t)}}(e,[]),n}(e,t);if(0===n.length)return[{tokens:e,term:e.map((e=>({value:e,presence:o().Query.presence.REQUIRED,wildcard:o().Query.wildcard.LEADING|o().Query.wildcard.TRAILING})))}];for(const o of n)o[o.length-1].maybeTyping=!0;const r=[];for(const i of a.dK)if("en"===i)a._k||r.unshift(o().stopWordFilter);else{const e=o()[i];e.stopWordFilter&&r.unshift(e.stopWordFilter)}let s;if(r.length>0){const e=e=>r.reduce(((e,t)=>e.filter((e=>t(e.value)))),e);s=[];const t=[];for(const r of n){const n=e(r);s.push(n),n.length0&&t.push(n)}n.push(...t)}else s=n.slice();const c=[];for(const o of s)if(o.length>2)for(let e=o.length-1;e>=0;e-=1)c.push(o.slice(0,e).concat(o.slice(e+1)));return i(n).concat(i(c))}(c,t),u=[];e:for(const{term:t,tokens:o}of l)for(const{documents:r,index:a,type:i}of e)if(u.push(...a.query((e=>{for(const n of t)e.term(n.value,{wildcard:n.wildcard,presence:n.presence})})).slice(0,n).filter((e=>!u.some((t=>t.document.i.toString()===e.ref)))).slice(0,n-u.length).map((t=>{const n=r.find((e=>e.i.toString()===t.ref));return{document:n,type:i,page:0!==i&&e[0].documents.find((e=>e.i===n.p)),metadata:t.matchData.metadata,tokens:o,score:t.score}}))),u.length>=n)break e;!function(e){e.forEach(((e,t)=>{e.index=t})),e.sort(((t,n)=>{let r=t.type>0&&t.page?e.findIndex((e=>e.document===t.page)):t.index,o=n.type>0&&n.page?e.findIndex((e=>e.document===n.page)):n.index;return-1===r&&(r=t.index),-1===o&&(o=n.index),r===o?0===t.type?-1:0===n.type?1:t.index-n.index:r-o}))}(u),function(e){e.forEach(((t,n)=>{n>0&&t.page&&e.some((e=>e.document===t.page))&&(n{"use strict";function r(e){return e.join(" \u203a ")}n.d(t,{e:()=>r})},21690:(e,t,n)=>{"use strict";function r(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}n.d(t,{X:()=>r})},91073:(e,t,n)=>{"use strict";function r(e,t){const n=[];for(const r of Object.values(e))r[t]&&n.push(...r[t].position);return n.sort(((e,t)=>e[0]-t[0]||t[1]-e[1]))}n.d(t,{m:()=>r})},82539:(e,t,n)=>{"use strict";n.d(t,{C:()=>o});var r=n(21690);function o(e,t,n){const a=[];for(const i of t){const n=e.toLowerCase().indexOf(i);if(n>=0){n>0&&a.push(o(e.substr(0,n),t)),a.push(`${(0,r.X)(e.substr(n,i.length))}`);const s=n+i.length;s${(0,r.X)(e)}`:(0,r.X)(e):a.join("")}},10726:(e,t,n)=>{"use strict";n.d(t,{o:()=>c});var r=n(21690),o=n(82539);const a=/\w+|\p{Unified_Ideograph}/u;function i(e){const t=[];let n=0,r=e;for(;r.length>0;){const o=r.match(a);if(!o){t.push(r);break}o.index>0&&t.push(r.substring(0,o.index)),t.push(o[0]),n+=o.index+o[0].length,r=e.substring(n)}return t}var s=n(61029);function c(e,t,n,a){void 0===a&&(a=s.Hk);const{chunkIndex:c,chunks:l}=function(e,t,n){const a=[];let s=0,c=0,l=-1;for(;sc){const t=i(e.substring(c,u)).map((e=>({html:(0,r.X)(e),textLength:e.length})));for(const e of t)a.push(e)}-1===l&&(l=a.length),c=u+d,a.push({html:(0,o.C)(e.substring(u,c),n,!0),textLength:d})}}if(c({html:(0,r.X)(e),textLength:e.length})));for(const e of t)a.push(e)}return{chunkIndex:l,chunks:a}}(e,t,n),u=l.slice(0,c),d=l[c],p=[d.html],f=l.slice(c+1);let m=d.textLength,h=0,g=0,b=!1,y=!1;for(;m0){const e=u.pop();m+e.textLength<=a?(p.unshift(e.html),h+=e.textLength,m+=e.textLength):(b=!0,u.length=0)}else{if(!(f.length>0))break;{const e=f.shift();m+e.textLength<=a?(p.push(e.html),g+=e.textLength,m+=e.textLength):(y=!0,f.length=0)}}return(b||u.length>0)&&p.unshift("\u2026"),(y||f.length>0)&&p.push("\u2026"),p.join("")}},50051:(e,t,n)=>{"use strict";function r(e,t){if("string"==typeof e)return{label:e,path:e};{const{label:n,path:r}=e;return"string"==typeof n?{label:n,path:r}:Object.prototype.hasOwnProperty.call(n,t)?{label:n[t],path:r}:{label:r,path:r}}}n.d(t,{_:()=>r})},61029:(e,t,n)=>{"use strict";n.d(t,{vc:()=>a,gQ:()=>f,H6:()=>l,hG:()=>g,l9:()=>m,dK:()=>r,_k:()=>o,pu:()=>p,AY:()=>u,t_:()=>d,Kc:()=>h,J:()=>i,Hk:()=>c,qo:()=>s,pQ:()=>b});n(31336);const r=["en"],o=!1,a=null,i="search-index{dir}.json?_=5d5de841",s=8,c=50,l=!1,u=!0,d=!1,p="right",f=void 0,m=!0,h=["learn","ecosystem"],g=!1,b=!0},99318:(e,t,n)=>{"use strict";n.d(t,{lX:()=>_,q_:()=>E,ob:()=>f,PP:()=>P,Ep:()=>p});var r=n(87462);function o(e){return"/"===e.charAt(0)}function a(e,t){for(var n=t,r=n+1,o=e.length;r=0;p--){var f=i[p];"."===f?a(i,p):".."===f?(a(i,p),d++):d&&(a(i,p),d--)}if(!l)for(;d--;d)i.unshift("..");!l||""===i[0]||i[0]&&o(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var s=n(38776);function c(e){return"/"===e.charAt(0)?e:"/"+e}function l(e){return"/"===e.charAt(0)?e.substr(1):e}function u(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function p(e){var t=e.pathname,n=e.search,r=e.hash,o=t||"/";return n&&"?"!==n&&(o+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(o+="#"===r.charAt(0)?r:"#"+r),o}function f(e,t,n,o){var a;"string"==typeof e?(a=function(e){var t=e||"/",n="",r="",o=t.indexOf("#");-1!==o&&(r=t.substr(o),t=t.substr(0,o));var a=t.indexOf("?");return-1!==a&&(n=t.substr(a),t=t.substr(0,a)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),a.state=t):(void 0===(a=(0,r.Z)({},e)).pathname&&(a.pathname=""),a.search?"?"!==a.search.charAt(0)&&(a.search="?"+a.search):a.search="",a.hash?"#"!==a.hash.charAt(0)&&(a.hash="#"+a.hash):a.hash="",void 0!==t&&void 0===a.state&&(a.state=t));try{a.pathname=decodeURI(a.pathname)}catch(s){throw s instanceof URIError?new URIError('Pathname "'+a.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):s}return n&&(a.key=n),o?a.pathname?"/"!==a.pathname.charAt(0)&&(a.pathname=i(a.pathname,o.pathname)):a.pathname=o.pathname:a.pathname||(a.pathname="/"),a}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,o){if(null!=e){var a="function"==typeof e?e(t,n):e;"string"==typeof a?"function"==typeof r?r(a,o):o(!0):o(!1!==a)}else o(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,o):n.push(o),d({action:r,location:o,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",o=f(e,t,h(),_.location);u.confirmTransitionTo(o,r,n,(function(e){e&&(_.entries[_.index]=o,d({action:r,location:o}))}))},go:v,goBack:function(){v(-1)},goForward:function(){v(1)},canGo:function(e){var t=_.index+e;return t>=0&&t<_.entries.length},block:function(e){return void 0===e&&(e=!1),u.setPrompt(e)},listen:function(e){return u.appendListener(e)}};return _}},8679:(e,t,n)=>{"use strict";var r=n(59864),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function c(e){return r.isMemo(e)?i:s[e.$$typeof]||o}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var l=Object.defineProperty,u=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,p=Object.getOwnPropertyDescriptor,f=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var o=f(n);o&&o!==m&&e(t,o,r)}var i=u(n);d&&(i=i.concat(d(n)));for(var s=c(t),h=c(n),g=0;g{"use strict";e.exports=function(e,t,n,r,o,a,i,s){if(!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,a,i,s],u=0;(c=new Error(t.replace(/%s/g,(function(){return l[u++]})))).name="Invariant Violation"}throw c.framesToPop=1,c}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},31336:(e,t,n)=>{var r,o;!function(){var a,i,s,c,l,u,d,p,f,m,h,g,b,y,v,_,w,k,x,S,C,E,T,P,L,j,O,N,A,I,R=function(e){var t=new R.Builder;return t.pipeline.add(R.trimmer,R.stopWordFilter,R.stemmer),t.searchPipeline.add(R.stemmer),e.call(t,t),t.build()};R.version="2.3.9",R.utils={},R.utils.warn=(a=this,function(e){a.console&&console.warn&&console.warn(e)}),R.utils.asString=function(e){return null==e?"":e.toString()},R.utils.clone=function(e){if(null==e)return e;for(var t=Object.create(null),n=Object.keys(e),r=0;r0){var c=R.utils.clone(t)||{};c.position=[i,s],c.index=o.length,o.push(new R.Token(n.slice(i,a),c))}i=a+1}}return o},R.tokenizer.separator=/[\s\-]+/,R.Pipeline=function(){this._stack=[]},R.Pipeline.registeredFunctions=Object.create(null),R.Pipeline.registerFunction=function(e,t){t in this.registeredFunctions&&R.utils.warn("Overwriting existing registered function: "+t),e.label=t,R.Pipeline.registeredFunctions[e.label]=e},R.Pipeline.warnIfFunctionNotRegistered=function(e){e.label&&e.label in this.registeredFunctions||R.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},R.Pipeline.load=function(e){var t=new R.Pipeline;return e.forEach((function(e){var n=R.Pipeline.registeredFunctions[e];if(!n)throw new Error("Cannot load unregistered function: "+e);t.add(n)})),t},R.Pipeline.prototype.add=function(){Array.prototype.slice.call(arguments).forEach((function(e){R.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)}),this)},R.Pipeline.prototype.after=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");n+=1,this._stack.splice(n,0,t)},R.Pipeline.prototype.before=function(e,t){R.Pipeline.warnIfFunctionNotRegistered(t);var n=this._stack.indexOf(e);if(-1==n)throw new Error("Cannot find existingFn");this._stack.splice(n,0,t)},R.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);-1!=t&&this._stack.splice(t,1)},R.Pipeline.prototype.run=function(e){for(var t=this._stack.length,n=0;n1&&(ae&&(n=o),a!=e);)r=n-t,o=t+Math.floor(r/2),a=this.elements[2*o];return a==e||a>e?2*o:as?l+=2:i==s&&(t+=n[c+1]*r[l+1],c+=2,l+=2);return t},R.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},R.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,n=0;t0){var a,i=o.str.charAt(0);i in o.node.edges?a=o.node.edges[i]:(a=new R.TokenSet,o.node.edges[i]=a),1==o.str.length&&(a.final=!0),r.push({node:a,editsRemaining:o.editsRemaining,str:o.str.slice(1)})}if(0!=o.editsRemaining){if("*"in o.node.edges)var s=o.node.edges["*"];else{s=new R.TokenSet;o.node.edges["*"]=s}if(0==o.str.length&&(s.final=!0),r.push({node:s,editsRemaining:o.editsRemaining-1,str:o.str}),o.str.length>1&&r.push({node:o.node,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)}),1==o.str.length&&(o.node.final=!0),o.str.length>=1){if("*"in o.node.edges)var c=o.node.edges["*"];else{c=new R.TokenSet;o.node.edges["*"]=c}1==o.str.length&&(c.final=!0),r.push({node:c,editsRemaining:o.editsRemaining-1,str:o.str.slice(1)})}if(o.str.length>1){var l,u=o.str.charAt(0),d=o.str.charAt(1);d in o.node.edges?l=o.node.edges[d]:(l=new R.TokenSet,o.node.edges[d]=l),1==o.str.length&&(l.final=!0),r.push({node:l,editsRemaining:o.editsRemaining-1,str:u+o.str.slice(2)})}}}return n},R.TokenSet.fromString=function(e){for(var t=new R.TokenSet,n=t,r=0,o=e.length;r=e;t--){var n=this.uncheckedNodes[t],r=n.child.toString();r in this.minimizedNodes?n.parent.edges[n.char]=this.minimizedNodes[r]:(n.child._str=r,this.minimizedNodes[r]=n.child),this.uncheckedNodes.pop()}},R.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},R.Index.prototype.search=function(e){return this.query((function(t){new R.QueryParser(e,t).parse()}))},R.Index.prototype.query=function(e){for(var t=new R.Query(this.fields),n=Object.create(null),r=Object.create(null),o=Object.create(null),a=Object.create(null),i=Object.create(null),s=0;s1?1:e},R.Builder.prototype.k1=function(e){this._k1=e},R.Builder.prototype.add=function(e,t){var n=e[this._ref],r=Object.keys(this._fields);this._documents[n]=t||{},this.documentCount+=1;for(var o=0;o=this.length)return R.QueryLexer.EOS;var e=this.str.charAt(this.pos);return this.pos+=1,e},R.QueryLexer.prototype.width=function(){return this.pos-this.start},R.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},R.QueryLexer.prototype.backup=function(){this.pos-=1},R.QueryLexer.prototype.acceptDigitRun=function(){var e,t;do{t=(e=this.next()).charCodeAt(0)}while(t>47&&t<58);e!=R.QueryLexer.EOS&&this.backup()},R.QueryLexer.prototype.more=function(){return this.pos1&&(e.backup(),e.emit(R.QueryLexer.TERM)),e.ignore(),e.more())return R.QueryLexer.lexText},R.QueryLexer.lexEditDistance=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.EDIT_DISTANCE),R.QueryLexer.lexText},R.QueryLexer.lexBoost=function(e){return e.ignore(),e.acceptDigitRun(),e.emit(R.QueryLexer.BOOST),R.QueryLexer.lexText},R.QueryLexer.lexEOS=function(e){e.width()>0&&e.emit(R.QueryLexer.TERM)},R.QueryLexer.termSeparator=R.tokenizer.separator,R.QueryLexer.lexText=function(e){for(;;){var t=e.next();if(t==R.QueryLexer.EOS)return R.QueryLexer.lexEOS;if(92!=t.charCodeAt(0)){if(":"==t)return R.QueryLexer.lexField;if("~"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexEditDistance;if("^"==t)return e.backup(),e.width()>0&&e.emit(R.QueryLexer.TERM),R.QueryLexer.lexBoost;if("+"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if("-"==t&&1===e.width())return e.emit(R.QueryLexer.PRESENCE),R.QueryLexer.lexText;if(t.match(R.QueryLexer.termSeparator))return R.QueryLexer.lexTerm}else e.escapeCharacter()}},R.QueryParser=function(e,t){this.lexer=new R.QueryLexer(e),this.query=t,this.currentClause={},this.lexemeIdx=0},R.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var e=R.QueryParser.parseClause;e;)e=e(this);return this.query},R.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},R.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},R.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},R.QueryParser.parseClause=function(e){var t=e.peekLexeme();if(null!=t)switch(t.type){case R.QueryLexer.PRESENCE:return R.QueryParser.parsePresence;case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:var n="expected either a field or a term, found "+t.type;throw t.str.length>=1&&(n+=" with value '"+t.str+"'"),new R.QueryParseError(n,t.start,t.end)}},R.QueryParser.parsePresence=function(e){var t=e.consumeLexeme();if(null!=t){switch(t.str){case"-":e.currentClause.presence=R.Query.presence.PROHIBITED;break;case"+":e.currentClause.presence=R.Query.presence.REQUIRED;break;default:var n="unrecognised presence operator'"+t.str+"'";throw new R.QueryParseError(n,t.start,t.end)}var r=e.peekLexeme();if(null==r){n="expecting term or field, found nothing";throw new R.QueryParseError(n,t.start,t.end)}switch(r.type){case R.QueryLexer.FIELD:return R.QueryParser.parseField;case R.QueryLexer.TERM:return R.QueryParser.parseTerm;default:n="expecting term or field, found '"+r.type+"'";throw new R.QueryParseError(n,r.start,r.end)}}},R.QueryParser.parseField=function(e){var t=e.consumeLexeme();if(null!=t){if(-1==e.query.allFields.indexOf(t.str)){var n=e.query.allFields.map((function(e){return"'"+e+"'"})).join(", "),r="unrecognised field '"+t.str+"', possible fields: "+n;throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.fields=[t.str];var o=e.peekLexeme();if(null==o){r="expecting term, found nothing";throw new R.QueryParseError(r,t.start,t.end)}if(o.type===R.QueryLexer.TERM)return R.QueryParser.parseTerm;r="expecting term, found '"+o.type+"'";throw new R.QueryParseError(r,o.start,o.end)}},R.QueryParser.parseTerm=function(e){var t=e.consumeLexeme();if(null!=t){e.currentClause.term=t.str.toLowerCase(),-1!=t.str.indexOf("*")&&(e.currentClause.usePipeline=!1);var n=e.peekLexeme();if(null!=n)switch(n.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:var r="Unexpected lexeme type '"+n.type+"'";throw new R.QueryParseError(r,n.start,n.end)}else e.nextClause()}},R.QueryParser.parseEditDistance=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="edit distance must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.editDistance=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new R.QueryParseError(r,o.start,o.end)}else e.nextClause()}},R.QueryParser.parseBoost=function(e){var t=e.consumeLexeme();if(null!=t){var n=parseInt(t.str,10);if(isNaN(n)){var r="boost must be numeric";throw new R.QueryParseError(r,t.start,t.end)}e.currentClause.boost=n;var o=e.peekLexeme();if(null!=o)switch(o.type){case R.QueryLexer.TERM:return e.nextClause(),R.QueryParser.parseTerm;case R.QueryLexer.FIELD:return e.nextClause(),R.QueryParser.parseField;case R.QueryLexer.EDIT_DISTANCE:return R.QueryParser.parseEditDistance;case R.QueryLexer.BOOST:return R.QueryParser.parseBoost;case R.QueryLexer.PRESENCE:return e.nextClause(),R.QueryParser.parsePresence;default:r="Unexpected lexeme type '"+o.type+"'";throw new R.QueryParseError(r,o.start,o.end)}else e.nextClause()}},void 0===(o="function"==typeof(r=function(){return R})?r.call(t,n,t,e):r)||(e.exports=o)}()},32497:(e,t,n)=>{"use strict";n.r(t)},52295:(e,t,n)=>{"use strict";n.r(t)},652:(e,t,n)=>{"use strict";n.r(t)},5554:(e,t,n)=>{"use strict";n.r(t)},74865:function(e,t,n){var r,o;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function o(e,t,n){return en?n:e}function a(e){return 100*(-1+e)}function i(e,t,n){var o;return(o="translate3d"===r.positionUsing?{transform:"translate3d("+a(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+a(e)+"%,0)"}:{"margin-left":a(e)+"%"}).transition="all "+t+"ms "+n,o}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=o(e,r.minimum,1),n.status=1===e?null:e;var a=n.render(!t),l=a.querySelector(r.barSelector),u=r.speed,d=r.easing;return a.offsetWidth,s((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),c(l,i(e,u,d)),1===e?(c(a,{transition:"none",opacity:1}),a.offsetWidth,setTimeout((function(){c(a,{transition:"all "+u+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),u)}),u)):setTimeout(t,u)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*o(Math.random()*t,.1,.95)),t=o(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");u(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var o,i=t.querySelector(r.barSelector),s=e?"-100":a(n.status||0),l=document.querySelector(r.parent);return c(i,{transition:"all 0 linear",transform:"translate3d("+s+"%,0,0)"}),r.showSpinner||(o=t.querySelector(r.spinnerSelector))&&f(o),l!=document.body&&u(l,"nprogress-custom-parent"),l.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&f(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var s=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),c=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,o=e.length,a=t.charAt(0).toUpperCase()+t.slice(1);o--;)if((r=e[o]+a)in n)return r;return t}function o(e){return e=n(e),t[e]||(t[e]=r(e))}function a(e,t,n){t=o(t),e.style[t]=n}return function(e,t){var n,r,o=arguments;if(2==o.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&a(e,n,r);else a(e,o[1],o[2])}}();function l(e,t){return("string"==typeof e?e:p(e)).indexOf(" "+t+" ")>=0}function u(e,t){var n=p(e),r=n+t;l(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=p(e);l(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function p(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function f(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(o="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=o)},14779:(e,t,n)=>{var r=n(5826);e.exports=f,e.exports.parse=a,e.exports.compile=function(e,t){return s(a(e,t),t)},e.exports.tokensToFunction=s,e.exports.tokensToRegExp=p;var o=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function a(e,t){for(var n,r=[],a=0,i=0,s="",u=t&&t.delimiter||"/";null!=(n=o.exec(e));){var d=n[0],p=n[1],f=n.index;if(s+=e.slice(i,f),i=f+d.length,p)s+=p[1];else{var m=e[i],h=n[2],g=n[3],b=n[4],y=n[5],v=n[6],_=n[7];s&&(r.push(s),s="");var w=null!=h&&null!=m&&m!==h,k="+"===v||"*"===v,x="?"===v||"*"===v,S=n[2]||u,C=b||y;r.push({name:g||a++,prefix:h||"",delimiter:S,optional:x,repeat:k,partial:w,asterisk:!!_,pattern:C?l(C):_?".*":"[^"+c(S)+"]+?"})}}return i{!function(e){var t={pattern:/((?:^|[^\\$])(?:\\{2})*)\$(?:\w+|\{[^{}]*\})/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:null}}};e.languages.groovy=e.languages.extend("clike",{string:{pattern:/'''(?:[^\\]|\\[\s\S])*?'''|'(?:\\.|[^\\'\r\n])*'/,greedy:!0},keyword:/\b(?:abstract|as|assert|boolean|break|byte|case|catch|char|class|const|continue|def|default|do|double|else|enum|extends|final|finally|float|for|goto|if|implements|import|in|instanceof|int|interface|long|native|new|package|private|protected|public|return|short|static|strictfp|super|switch|synchronized|this|throw|throws|trait|transient|try|void|volatile|while)\b/,number:/\b(?:0b[01_]+|0x[\da-f_]+(?:\.[\da-f_p\-]+)?|[\d_]+(?:\.[\d_]+)?(?:e[+-]?\d+)?)[glidf]?\b/i,operator:{pattern:/(^|[^.])(?:~|==?~?|\?[.:]?|\*(?:[.=]|\*=?)?|\.[@&]|\.\.<|\.\.(?!\.)|-[-=>]?|\+[+=]?|!=?|<(?:<=?|=>?)?|>(?:>>?=?|=)?|&[&=]?|\|[|=]?|\/=?|\^=?|%=?)/,lookbehind:!0},punctuation:/\.+|[{}[\];(),:$]/}),e.languages.insertBefore("groovy","string",{shebang:{pattern:/#!.+/,alias:"comment",greedy:!0},"interpolation-string":{pattern:/"""(?:[^\\]|\\[\s\S])*?"""|(["/])(?:\\.|(?!\1)[^\\\r\n])*\1|\$\/(?:[^/$]|\$(?:[/$]|(?![/$]))|\/(?!\$))*\/\$/,greedy:!0,inside:{interpolation:t,string:/[\s\S]+/}}}),e.languages.insertBefore("groovy","punctuation",{"spock-block":/\b(?:and|cleanup|expect|given|setup|then|when|where):/}),e.languages.insertBefore("groovy","function",{annotation:{pattern:/(^|[^.])@\w+/,lookbehind:!0,alias:"punctuation"}}),t.inside.expression.inside=e.languages.groovy}(Prism)},81295:()=>{Prism.languages.haskell={comment:{pattern:/(^|[^-!#$%*+=?&@|~.:<>^\\\/])(?:--(?:(?=.)[^-!#$%*+=?&@|~.:<>^\\\/].*|$)|\{-[\s\S]*?-\})/m,lookbehind:!0},char:{pattern:/'(?:[^\\']|\\(?:[abfnrtv\\"'&]|\^[A-Z@[\]^_]|ACK|BEL|BS|CAN|CR|DC1|DC2|DC3|DC4|DEL|DLE|EM|ENQ|EOT|ESC|ETB|ETX|FF|FS|GS|HT|LF|NAK|NUL|RS|SI|SO|SOH|SP|STX|SUB|SYN|US|VT|\d+|o[0-7]+|x[0-9a-fA-F]+))'/,alias:"string"},string:{pattern:/"(?:[^\\"]|\\(?:\S|\s+\\))*"/,greedy:!0},keyword:/\b(?:case|class|data|deriving|do|else|if|in|infixl|infixr|instance|let|module|newtype|of|primitive|then|type|where)\b/,"import-statement":{pattern:/(^[\t ]*)import\s+(?:qualified\s+)?(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*(?:\s+as\s+(?:[A-Z][\w']*)(?:\.[A-Z][\w']*)*)?(?:\s+hiding\b)?/m,lookbehind:!0,inside:{keyword:/\b(?:as|hiding|import|qualified)\b/,punctuation:/\./}},builtin:/\b(?:abs|acos|acosh|all|and|any|appendFile|approxRational|asTypeOf|asin|asinh|atan|atan2|atanh|basicIORun|break|catch|ceiling|chr|compare|concat|concatMap|const|cos|cosh|curry|cycle|decodeFloat|denominator|digitToInt|div|divMod|drop|dropWhile|either|elem|encodeFloat|enumFrom|enumFromThen|enumFromThenTo|enumFromTo|error|even|exp|exponent|fail|filter|flip|floatDigits|floatRadix|floatRange|floor|fmap|foldl|foldl1|foldr|foldr1|fromDouble|fromEnum|fromInt|fromInteger|fromIntegral|fromRational|fst|gcd|getChar|getContents|getLine|group|head|id|inRange|index|init|intToDigit|interact|ioError|isAlpha|isAlphaNum|isAscii|isControl|isDenormalized|isDigit|isHexDigit|isIEEE|isInfinite|isLower|isNaN|isNegativeZero|isOctDigit|isPrint|isSpace|isUpper|iterate|last|lcm|length|lex|lexDigits|lexLitChar|lines|log|logBase|lookup|map|mapM|mapM_|max|maxBound|maximum|maybe|min|minBound|minimum|mod|negate|not|notElem|null|numerator|odd|or|ord|otherwise|pack|pi|pred|primExitWith|print|product|properFraction|putChar|putStr|putStrLn|quot|quotRem|range|rangeSize|read|readDec|readFile|readFloat|readHex|readIO|readInt|readList|readLitChar|readLn|readOct|readParen|readSigned|reads|readsPrec|realToFrac|recip|rem|repeat|replicate|return|reverse|round|scaleFloat|scanl|scanl1|scanr|scanr1|seq|sequence|sequence_|show|showChar|showInt|showList|showLitChar|showParen|showSigned|showString|shows|showsPrec|significand|signum|sin|sinh|snd|sort|span|splitAt|sqrt|subtract|succ|sum|tail|take|takeWhile|tan|tanh|threadToIOResult|toEnum|toInt|toInteger|toLower|toRational|toUpper|truncate|uncurry|undefined|unlines|until|unwords|unzip|unzip3|userError|words|writeFile|zip|zip3|zipWith|zipWith3)\b/,number:/\b(?:\d+(?:\.\d+)?(?:e[+-]?\d+)?|0o[0-7]+|0x[0-9a-f]+)\b/i,operator:[{pattern:/`(?:[A-Z][\w']*\.)*[_a-z][\w']*`/,greedy:!0},{pattern:/(\s)\.(?=\s)/,lookbehind:!0},/[-!#$%*+=?&@|~:<>^\\\/][-!#$%*+=?&@|~.:<>^\\\/]*|\.[-!#$%*+=?&@|~.:<>^\\\/]+/],hvariable:{pattern:/\b(?:[A-Z][\w']*\.)*[_a-z][\w']*/,inside:{punctuation:/\./}},constant:{pattern:/\b(?:[A-Z][\w']*\.)*[A-Z][\w']*/,inside:{punctuation:/\./}},punctuation:/[{}[\];(),.:]/},Prism.languages.hs=Prism.languages.haskell},52503:()=>{!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record(?!\s*[(){}[\]<>=%~.:,;?+\-*/&|^])|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n=/(?:[a-z]\w*\s*\.\s*)*(?:[A-Z]\w*\s*\.\s*)*/.source,r={pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z](?:[\d_A-Z]*[a-z]\w*)?\b/.source),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"/,lookbehind:!0,greedy:!0},"class-name":[r,{pattern:RegExp(/(^|[^\w.])/.source+n+/[A-Z]\w*(?=\s+\w+\s*[;,=()]|\s*(?:\[[\s,]*\]\s*)?::\s*new\b)/.source),lookbehind:!0,inside:r.inside},{pattern:RegExp(/(\b(?:class|enum|extends|implements|instanceof|interface|new|record|throws)\s+)/.source+n+/[A-Z]\w*\b/.source),lookbehind:!0,inside:r.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(::\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0},constant:/\b[A-Z][A-Z_\d]+\b/}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"},char:{pattern:/'(?:\\.|[^'\\\r\n]){1,6}'/,greedy:!0}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":r,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},import:[{pattern:RegExp(/(\bimport\s+)/.source+n+/(?:[A-Z]\w*|\*)(?=\s*;)/.source),lookbehind:!0,inside:{namespace:r.inside.namespace,punctuation:/\./,operator:/\*/,"class-name":/\w+/}},{pattern:RegExp(/(\bimport\s+static\s+)/.source+n+/(?:\w+|\*)(?=\s*;)/.source),lookbehind:!0,alias:"static",inside:{namespace:r.inside.namespace,static:/\b\w+$/,punctuation:/\./,operator:/\*/,"class-name":/\w+/}}],namespace:{pattern:RegExp(/(\b(?:exports|import(?:\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\s+)(?!)[a-z]\w*(?:\.[a-z]\w*)*\.?/.source.replace(//g,(function(){return t.source}))),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism)},32334:()=>{!function(e){e.languages.kotlin=e.languages.extend("clike",{keyword:{pattern:/(^|[^.])\b(?:abstract|actual|annotation|as|break|by|catch|class|companion|const|constructor|continue|crossinline|data|do|dynamic|else|enum|expect|external|final|finally|for|fun|get|if|import|in|infix|init|inline|inner|interface|internal|is|lateinit|noinline|null|object|open|operator|out|override|package|private|protected|public|reified|return|sealed|set|super|suspend|tailrec|this|throw|to|try|typealias|val|var|vararg|when|where|while)\b/,lookbehind:!0},function:[{pattern:/(?:`[^\r\n`]+`|\b\w+)(?=\s*\()/,greedy:!0},{pattern:/(\.)(?:`[^\r\n`]+`|\w+)(?=\s*\{)/,lookbehind:!0,greedy:!0}],number:/\b(?:0[xX][\da-fA-F]+(?:_[\da-fA-F]+)*|0[bB][01]+(?:_[01]+)*|\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?(?:[eE][+-]?\d+(?:_\d+)*)?[fFL]?)\b/,operator:/\+[+=]?|-[-=>]?|==?=?|!(?:!|==?)?|[\/*%<>]=?|[?:]:?|\.\.|&&|\|\||\b(?:and|inv|or|shl|shr|ushr|xor)\b/}),delete e.languages.kotlin["class-name"];var t={"interpolation-punctuation":{pattern:/^\$\{?|\}$/,alias:"punctuation"},expression:{pattern:/[\s\S]+/,inside:e.languages.kotlin}};e.languages.insertBefore("kotlin","string",{"string-literal":[{pattern:/"""(?:[^$]|\$(?:(?!\{)|\{[^{}]*\}))*?"""/,alias:"multiline",inside:{interpolation:{pattern:/\$(?:[a-z_]\w*|\{[^{}]*\})/i,inside:t},string:/[\s\S]+/}},{pattern:/"(?:[^"\\\r\n$]|\\.|\$(?:(?!\{)|\{[^{}]*\}))*"/,alias:"singleline",inside:{interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$(?:[a-z_]\w*|\{[^{}]*\})/i,lookbehind:!0,inside:t},string:/[\s\S]+/}}],char:{pattern:/'(?:[^'\\\r\n]|\\(?:.|u[a-fA-F0-9]{0,4}))'/,greedy:!0}}),delete e.languages.kotlin.string,e.languages.insertBefore("kotlin","keyword",{annotation:{pattern:/\B@(?:\w+:)?(?:[A-Z]\w*|\[[^\]]+\])/,alias:"builtin"}}),e.languages.insertBefore("kotlin","function",{label:{pattern:/\b\w+@|@\w+\b/,alias:"symbol"}}),e.languages.kt=e.languages.kotlin,e.languages.kts=e.languages.kotlin}(Prism)},96854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,o,a){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(o,(function(e){if("function"==typeof a&&!a(e))return e;for(var o,s=i.length;-1!==n.code.indexOf(o=t(r,s));)++s;return i[s]=e,o})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var o=0,a=Object.keys(n.tokenStack);!function i(s){for(var c=0;c=a.length);c++){var l=s[c];if("string"==typeof l||l.content&&"string"==typeof l.content){var u=a[o],d=n.tokenStack[u],p="string"==typeof l?l:l.content,f=t(r,u),m=p.indexOf(f);if(m>-1){++o;var h=p.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=p.substring(m+f.length),y=[];h&&y.push.apply(y,i([h])),y.push(g),b&&y.push.apply(y,i([b])),"string"==typeof l?s.splice.apply(s,[c,1].concat(y)):l.content=y}}else l.content&&i(l.content)}return s}(n.tokens)}}}})}(Prism)},12886:()=>{Prism.languages.scala=Prism.languages.extend("java",{"triple-quoted-string":{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string"},string:{pattern:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,greedy:!0},keyword:/<-|=>|\b(?:abstract|case|catch|class|def|derives|do|else|enum|extends|extension|final|finally|for|forSome|given|if|implicit|import|infix|inline|lazy|match|new|null|object|opaque|open|override|package|private|protected|return|sealed|self|super|this|throw|trait|transparent|try|type|using|val|var|while|with|yield)\b/,number:/\b0x(?:[\da-f]*\.)?[\da-f]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e\d+)?[dfl]?/i,builtin:/\b(?:Any|AnyRef|AnyVal|Boolean|Byte|Char|Double|Float|Int|Long|Nothing|Short|String|Unit)\b/,symbol:/'[^\d\s\\]\w*/}),Prism.languages.insertBefore("scala","triple-quoted-string",{"string-interpolation":{pattern:/\b[a-z]\w*(?:"""(?:[^$]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*?"""|"(?:[^$"\r\n]|\$(?:[^{]|\{(?:[^{}]|\{[^{}]*\})*\}))*")/i,greedy:!0,inside:{id:{pattern:/^\w+/,greedy:!0,alias:"function"},escape:{pattern:/\\\$"|\$[$"]/,greedy:!0,alias:"symbol"},interpolation:{pattern:/\$(?:\w+|\{(?:[^{}]|\{[^{}]*\})*\})/,greedy:!0,inside:{punctuation:/^\$\{?|\}$/,expression:{pattern:/[\s\S]+/,inside:Prism.languages.scala}}},string:/[\s\S]+/}}}),delete Prism.languages.scala["class-name"],delete Prism.languages.scala.function,delete Prism.languages.scala.constant},20775:(e,t,n)=>{var r={"./prism-groovy":40485,"./prism-haskell":81295,"./prism-java":52503,"./prism-kotlin":32334,"./prism-scala":12886};function o(e){var t=a(e);return n(t)}function a(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}o.keys=function(){return Object.keys(r)},o.resolve=a,e.exports=o,o.id=20775},92703:(e,t,n)=>{"use strict";var r=n(50414);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},64448:(e,t,n)=>{"use strict";var r=n(67294),o=n(63840);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n