Go to content
The Codest
  • About Us
    • Staff Augmentation
    • Project Development
    • Cloud Engineering
    • Quality Assurance
    • Web Development
  • Our Team
  • Case studies
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
  • About Us
    • Staff Augmentation
    • Project Development
    • Cloud Engineering
    • Quality Assurance
    • Web Development
  • Our Team
  • Case studies
    • Blog
    • Meetups
    • Webinars
    • Resources
Careers Get in touch
Content
2022-06-21
Software Development

Functional programming in JavaScript Part 3 - Functor & Monad Maybe

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

3 Useful HTML Tags You Might Not Know Even Existed

Nowadays, accessibility (A11y) is crucial on all stages of building custom software products. Starting from the UX/UI design part, it trespasses into advanced levels of building features in code. It provides tons of benefits for...

Jacek Ludzik
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
Technology news

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

Jakub Jakubowicz
Software Development

Functional Programming in JavaScript Part 1 – Introduction

Read our article to discover the power of functional programming in JavaScript. Functional programming is classified as a declarative paradigm where the program description is separated from the calculations.

Pawel Ged
Software Development

Functional programming in JavaScript Part 2 - Combinators

This is a second part of our series of articles devoted to power of functional programming in JavaScript. Check this article to expand your knowledge on Combinators.

Pawel Ged

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

About us

The Codest – International Tech Software 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

    Services

  • PHP development
  • Java development
  • Python development
  • Ruby on Rails development
  • React Developers
  • Vue Developers
  • TypeScript Developers
  • DevOps
  • QA Engineers

    Resources

  • What are top CTOs and CIOs Challenges? [2022 updated]
  • Facts and Myths about Cooperating with External Software Development Partner
  • From the USA to Europe: Why do American startups decide to relocate to Europe
  • Privacy policy
  • Website terms of use

Copyright © 2023 by The Codest. All rights reserved.

We use cookies on the site for marketing, analytical and statistical purposes. By continuing to use, without changing your privacy settings, our site, you consent to the storage of cookies in your browser. You can always change the cookie settings in your browser. You can find more information in our Privacy Policy.