Giter Club home page Giter Club logo

gleam-validate's Introduction

Monadic Validation in Gleam!

You might currently be defaulting on a form of validation that isn't giving you every error. Let's take for example, loading environment variables.

We might start with some types defined to load our Env into.

import gleam/erlang/os

pub type DbUser {
  DbUser(value: String)
}

pub type DbPassword {
  DbPassword(value: String)
}

pub type Env {
  Env(db_user: DbUser, db_password: DbPassword)
}

And define a useful helper to give us a a precise error message when we can't find an env variable.

fn get_env_var(var_name: String) -> Result(String, String) {
  case os.get_env(var_name) {
    Ok(var) -> Ok(var)
    Error(_) -> Error("Could not find env variable:" <> var_name)
  }
}

But the typical way of composing this will only yield a single error message , even if both variables are missing

pub fn load_env () -> Result(String, String) {
  use db_user <- result.try(
    get_env_var("DB_USER")
    |> result.map(DbUser)
  )

  use db_password <- result.try(
     get_env_var("DB_PASSWORD")
     |> result.map(DbPassword)
  )

  Env(
    db_user: db_user,
    db_password: db_password,
  )
  |> Ok
}

Suppose we try starting the app without "DB_USER". We will see an error that it is missing, correct the error, then attempt to start the app only to recieve the next error in line! We should have returned them both the first time.

With validate_monadic, this is a small rewrite to fix. First the utility function must be adjusted.

import validate_monadic.{type Validation} as validate

fn get_env_var(var_name: String) -> Validation(String, String) {
  case os.get_env(var_name) {
    Ok(var) -> validate.succeed(var)
    Error(_) -> validate.error("Failed to find env variable: " <> var_name)
  }
}

Now we can write an improved load_env function

import validate_monadic.{type Validation} as validate
import gleam/function

pub fn load_env () -> Validation(Env, String) {
  let db_user =
    get_env_var("db_user")
    |> validate.map(DbUser)

  let db_password =
    get_env_var("db_password")
    |> validate.map(DbPassword)

  Env
  |> function.curry2
  |> validate.map(db_user, _)
  |> validate.and_map(db_password)
}

# Installation

```sh
gleam add validate_monadic
import validate_monadic as validate

Usage

This module is the minimal set of functions around a single type alias for Result so it may be used as a "validation monad".

The /examples folder contains two examples for full usage of this module, using every method contained in it.

Checkout out the examples here

Development

gleam run   # Run the project
gleam test  # Run the tests
gleam shell # Run an Erlang shell

gleam-validate's People

Contributors

abradley2 avatar

Stargazers

Luke Frisken avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.