window.pipedriveLeadboosterConfig = { base: 'leadbooster-chat.pipedrive.com', companyId: 11580370, playbookUuid: '22236db1-6d50-40c4-b48f-8b11262155be', version: 2, } ;(function () { var w = window if (w.LeadBooster) { console.warn('LeadBooster already exists') } else { w.LeadBooster = { q: [], on: function (n, h) { this.q.push({ t: 'o', n: n, h: h }) }, trigger: function (n) { this.q.push({ t: 't', n: n }) }, } } })() Functional programming in JavaScript Part 3 - Functor & Monad Maybe - The Codest
The Codest
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Industries
    • Fintech & Banking
    • E-commerce
    • Adtech
    • Healthtech
    • Manufacturing
    • Logistics
    • Automotive
    • IOT
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About us
  • Services
    • Software Development
      • Frontend Development
      • Backend Development
    • Staff Augmentation
      • Frontend Developers
      • Backend Developers
      • Data Engineers
      • Cloud Engineers
      • QA Engineers
      • Other
    • It Advisory
      • Audit & Consulting
  • Value for
    • CEO
    • CTO
    • Delivery Manager
  • Our team
  • Case Studies
  • Know How
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
Back arrow GO BACK
2022-06-21
Software Development

Functional programming in JavaScript Part 3 – Functor & Monad Maybe

The Codest

Pawel Ged

Vue.js Developer

Check the third part of our Power of functional programming in JavaScript article series. This time our JavaScript expert explains more about Functor and Monad Maybe.

Introduction

Often keeping unmodifiable is difficult to maintain. The pattern of wrapping data into a container comes to the rescue. It secures the values so that handling them is safe with the exclusion of side effects.

If you are new here make sure to check my last 2 parts regarding functional programming on The Codest blog about:

  • Part 1 – Introduction
  • Part 2 – Combinators

Functor

It has no complex logic. Its main task is to wrap the context and perform the functions it receives from the outside on them. Each time the value changes, a new container instance is repackaged and returned. When calling the map method, which takes a specific action, it returns a new container instance with the value returned by the passed function, while maintaining the non-modifiable principle.

Declaration

 const Functor = value => ({
     map: fn => Functor(fn(value)),
     chain: fn => fn(value),
     of: () => value
 });

map – useful when you want to change the state of a value in a container but don’t want to return it yet.

chain – used if you want to pass a value to a function without modifying the container state. Usually at the end of map calls.

of – return current value

Imperative example

const randomInt = (max) => Math.floor(Math.random() * (max + 1))

const randomNumber = randomInt(200) // returns number between 0 and 200

decrease(randomNumber) // returns (number between 0 and 200) - 1

Declarative example

const randomIntWrapper = (max) =>
Functor(max)
.map(increase) // max + 1
.map(multiplyBy(Math.random())) // Math.random() * (max + 1)
.map(Math.floor) // Math.floor(Math.random() * (max + 1))

const randomNumber = randomIntWrapper(200)

randomNumber.of() // returns number between 0 and 200
randomNumber.chain(decrease) // returns (number between 0 and 200) - 1

Monad

Sometimes, in addition to the functions that trigger the new state of the value, you need additional logic hidden in the container. This is where monad comes in handy, as it is an extension of functor. It can, for example, decide what should happen when the value has a certain value or what path the next actions are to take.

Monad Maybe

Monad maybe solves the problem of values that return not true. When this happens, subsequent map calls are ignored, but it allows you to return an alternative by calling the getOr method. It allows you to avoid the use of if / else operators, which are popular in imperative programming. This monad consists of three containers:

Nothing – runs when a value that is not true falls into the container or filter method returns false. It is used to simulate the execution of a function. This means that this container receives the function but does not execute it.

Just – this is the main container that performs all the functions, but if the value changes to a false value or filter method returns false, it will pass it to the Nothing container.

Maybe – I take the initial value and decide what container to call at the start.

Declaration

const Just = value => ({
map: fn => Maybe(fn(value)),
chain: fn => fn(value),
of: () => value,
getOr: () => value,
filter: fn => fn(value) ? Just(value) : Nothing(),
type: 'just'
});

const Nothing = () => ({
map: fn => Nothing(),
chain: fn => fn(),
of: () => Nothing(),
getOr: substitute => substitute,
filter: () => Nothing(),
type: 'nothing'
});

const Maybe = value =>
value === null || value === undefined || value.type === 'nothing'
? Nothing()
: Just(value)
table methods functor

Now let’s build the previous example about the condition. If max is greater than zero, the function will be executed. Otherwise, it will return 0.

Imperative example

const randomInt = (max) => {
if(max > 0) {
return Math.floor(Math.random() * (max + 1))
} else {
return 0
}
}

const bookMiddlePage = 200

const randomPage = randomInt(10) || bookMiddlePage // returns random
const randomPage = randomInt(-10) || bookMiddlePage // returns 200

Declarative example

const randomIntWrapper = (max) =>
Maybe(max)
.filter(max => max > 0) // value false ignores further calls
.map(increase)
.map(multiplyBy(Math.random()))
.map(Math.floor)

const bookMiddlePage = 200

// Just container
const randomPage = randomIntWrapper(10).getOr(bookMiddlePage) // returns random
// Nothing container
const randomPage = randomIntWrapper(-10).getOr(bookMiddlePage) // returns 200


cooperation banner

Related articles

Software Development

Asynchronous and Single-threaded JavaScript?

JavaScript is a single-threaded language and, at the same time, also non-blocking, asynchronous and concurrent. This article will explain to you how it happens.

Lukasz Kolko
E-commerce

Cyber Security Dilemmas: Data Leaks

The pre-Christmas rush is in full swing. In search of gifts for their loved ones, people are increasingly willing to “storm” online shops

The Codest
Jakub Jakubowicz CTO & Co-Founder

Subscribe to our knowledge base and stay up to date on the expertise from the IT sector.

    About us

    The Codest – International software development company with tech hubs in Poland.

    United Kingdom - Headquarters

    • Office 303B, 182-184 High Street North E6 2JA
      London, England

    Poland - Local Tech Hubs

    • Fabryczna Office Park, Aleja
      Pokoju 18, 31-564 Kraków
    • Brain Embassy, Konstruktorska
      11, 02-673 Warsaw, Poland

      The Codest

    • Home
    • About us
    • Services
    • Case Studies
    • Know How
    • Careers
    • Dictionary

      Services

    • It Advisory
    • Software Development
    • Backend Development
    • Frontend Development
    • Staff Augmentation
    • Backend Developers
    • Cloud Engineers
    • Data Engineers
    • Other
    • QA Engineers

      Resources

    • Facts and Myths about Cooperating with External Software Development Partner
    • From the USA to Europe: Why do American startups decide to relocate to Europe
    • Tech Offshore Development Hubs Comparison: Tech Offshore Europe (Poland), ASEAN (Philippines), Eurasia (Turkey)
    • What are the top CTOs and CIOs Challenges?
    • The Codest
    • The Codest
    • The Codest
    • Privacy policy
    • Website terms of use

    Copyright © 2025 by The Codest. All rights reserved.

    en_USEnglish
    de_DEGerman sv_SESwedish da_DKDanish nb_NONorwegian fiFinnish fr_FRFrench pl_PLPolish arArabic it_ITItalian jaJapanese ko_KRKorean es_ESSpanish nl_NLDutch etEstonian elGreek en_USEnglish