[Functional Programming] Arrow Functor with contramap
What is Arrow Functor?
Arrow
is aProfunctor
that lifts a function of typea -> b
and allows for lazy execution of the function.Arrow
can be considered aStrong Profunctor
if the underlying data running through theArrow
is aPair
, typically in the form ofArrow (Pair a c) (Pair b d)
.This will allow you to split execution into two distinct paths, applying
Arrow
to a specific path. The parameters ofArrow
represent the function that it wraps, with the input being on the left, and the output on the right. When anArrow
wraps an endomorphism, the signature typically represents both the input and output.
In short, Arrow is
- Take a function
- Function will be lazy
- We can apply params later
const Arrow = require('crocks/Arrow'); const arrUpper = Arrow( str => str.toUpperCase() ) log( arrUpper.runWith('zhentian') ) // ZHENTIAN
Why this can be useful?
In this post, we are going to see an exmple about how to use 'Arrow' with 'contramap':
Currently 'arrUpper' take a string as input, sometimes the data we receive might be is an Object:
// {name: 'zhentian'}
In this case, we cannot directly using 'arrUpper', and we don't want to modify our 'arrUpper' function to be:
const arrUpper = Arrow(o => o.name && o.name.toUpperCase())
What we can do is using 'contramap' to apply an function on the input param of 'arrUpper', to change the Object type to String type, we can keep the 'arrUpper' untouched:
const Arrow = require('crocks/Arrow'); const chain = require('crocks/pointfree/chain'); const option = require('crocks/pointfree/option'); const prop = require('crocks/Maybe/prop'); const safe = require('crocks/Maybe/safe'); const getName = compose( option('no name'), chain(safe(isString)), prop('name') ) const arrUpper = Arrow( str => str.toUpperCase() ) const nameUpper = arrUpper .contramap(getName) log( nameUpper.runWith({name: 'zhentian'}) ) // ZHENTIAN
What 'contramap' does is apply the given function (getName) to the target function (arrUpper)'s params ({name: 'zhentian'}), before the target function get invoked.
So in our example, we transform the {name: 'zhentian'} to just 'zhentian' or 'no name' before passing to arrUpper.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2017-03-21 [RxJSv& Javascript] forkJoin (reactive Promise.all) & Map
2017-03-21 [Angular] FormBuildAPI
2017-03-21 [React Router v4] Render Multiple Components for the Same Route
2017-03-21 [React Router v4] Conditionally Render a Route with the Switch Component
2017-03-21 [React Router v4] Render Catch-All Routes with the Switch Component
2017-03-21 [React Router v4] Render Nested Routes
2017-03-21 [React Router v4] Parse Query Parameters