Gathering detailed insights and metrics for pratica
Gathering detailed insights and metrics for pratica
Gathering detailed insights and metrics for pratica
Gathering detailed insights and metrics for pratica
pratica-web
This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 8.2.0.
praticable-css
Modular css first created for praticable.fr
package-atividade-pratica-unidade-2-puc-minas
Publicacao do package da atividade pratica Node unidade 2 Puc Minas
prp-ui-components
Package for use components of Pratica Plataforms
npm install pratica
Typescript
Module System
Node Version
NPM Version
TypeScript (98.19%)
JavaScript (1.81%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
Apache-2.0 License
485 Stars
58 Commits
19 Forks
7 Watchers
1 Branches
7 Contributors
Updated on Jul 11, 2025
Latest Version
2.3.0
Package Id
pratica@2.3.0
Unpacked Size
93.03 kB
Size
31.63 kB
File Count
26
NPM Version
10.5.2
Node Version
20.13.1
Published on
Jun 05, 2024
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
5
Functional Programming for Pragmatists
Why is this for pragmatists you say?
Pratica sacrifices some common FP guidelines in order to provide a simpler and more approachable API that can be used to accomplish your goals quickly - while maintaining data integrity and safety, through algrebraic data types.
1bun i pratica 2# or 3yarn add pratica 4# or 5npm i pratica
Table of Contents
Use this when dealing with nullable and unreliable data that needs actions performed upon.
Maybe is great for making sure you do not cause runtime errors by accessing data that is not there because of unexpected nulls or undefineds.
Every Maybe can either be of type Just
or Nothing
. When the data is available, it is wrapped with Just
, if the data is missing, it is Nothing
. The examples below should clarify futher.
Map is used for running a function on the data inside the Maybe. Map will only run the function if the Maybe type is Just
. If it's Nothing, the map will short circuit and be skipped.
1import { nullable } from "pratica" 2 3const person = { name: "Jason", age: 4 } 4 5// Example with real data 6nullable(person) 7 .map((p) => p.age) 8 .map((age) => age + 5) 9 .cata({ 10 Just: (age) => console.log(age), // 9 11 Nothing: () => console.log(`This function won't run`), 12 }) 13 14// Example with null data 15nullable(null) 16 .map((p) => p.age) // Maybe type is Nothing, so this function is skipped 17 .map((age) => age + 5) // Maybe type is Nothing, so this function is skipped 18 .cata({ 19 Just: (age) => console.log(age), // Maybe type is Nothing, so this function is not run 20 Nothing: () => console.log("Could not get age from person"), // This function runs because Maybe is Nothing 21 })
Chain is used when you want to return another Maybe when already inside a Maybe.
1import { nullable } from "pratica" 2 3const person = { name: "Jason", age: 4 } 4 5nullable(person) 6 .chain((p) => nullable(p.height)) // p.height does not exist so nullable returns a Nothing type, any .map, .chain, or .ap after a Nothing will be short circuited 7 .map((height) => height * 2.2) // this func won't even run because height is Nothing, so `undefined * 2.2` will never execute, preventing problems. 8 .cata({ 9 Just: (height) => console.log(height), // this function won't run because the height is Nothing 10 Nothing: () => console.log("This person has no height"), 11 })
Alt is a clean way of making sure you always return a Just with some default data inside.
1import { nullable } from "pratica" 2 3// Example with default data 4nullable(null) 5 .map((p) => p.age) // won't run 6 .map((age) => age + 5) // won't run 7 .alt(99) // the data is null so 99 is the default 8 .cata({ 9 Just: (age) => console.log(age), // 99 10 Nothing: () => console.log(`This function won't run because .alt() always returns a Just`), 11 })
Sometime's working with Maybe can be reptitive to always call .map
whenever needing to a apply a function to the contents of the Maybe. Here is an example using .ap
to simplify this.
Goal of this example, to perform operations on data inside the Maybe, without unwrapping the data with .map
or .chain
1import { Just, nullable } from "pratica" 2 3// Need something like this 4// Just(6) + Just(7) = Just(13) 5Just((x) => (y) => x + y) 6 .ap(Just(6)) 7 .ap(Just(7)) 8 .cata({ 9 Just: (result) => console.log(result), // 13 10 Nothing: () => console.log(`This function won't run`), 11 }) 12 13nullable(null) // no function to apply 14 .ap(Just(6)) 15 .ap(Just(7)) 16 .cata({ 17 Just: () => console.log(`This function won't run`), 18 Nothing: () => console.log(`This function runs`), 19 })
Inspect is used for seeing a string respresentation of the Maybe. It is used mostly for Node logging which will automatically call inspect() on objects that have it, but you can use it too for debugging if you like.
1import { nullable } from "pratica" 2 3nullable(86).inspect() // `Just(86)` 4nullable("HELLO").inspect() // `Just('HELLO')` 5nullable(null).inspect() // `Nothing` 6nullable(undefined).inspect() // `Nothing`
Cata is used at the end of your chain of computations. It is used for getting the final data from the Maybe. You must pass an object to .cata
with 2 properties, Just
and Nothing
(capitalization matters), and both those properties must be a function. Those functions will run based on if the the computations above it return a Just or Nothing data type.
Cata stands for catamorphism and in simple terms means that it extracts a value from inside any container.
1import { Just, Nothing } from "pratica" 2 3const isOver6Feet = (person) => (person.height > 6 ? Just(person.height) : Nothing) 4 5isOver6Feet({ height: 4.5 }) 6 .map((h) => h / 2.2) 7 .cata({ 8 Just: (h) => console.log(h), // this function doesn't run 9 Nothing: () => console.log(`person is not over 6 feet`), 10 })
toResult is used for easily converting Maybe's to Result's. Any Maybe that is a Just will be converted to an Ok with the same value inside, and any value that was Nothing will be converted to an Err with no value passed. The cata will have to include Ok
and Err
instead of Just
and Nothing
.
1import { Just, Nothing } from "pratica" 2 3Just(8) 4 .toResult() 5 .cata({ 6 Ok: (n) => console.log(n), // 8 7 Err: () => console.log(`No value`), // this function doesn't run 8 }) 9 10Nothing.toResult().cata({ 11 Ok: (n) => console.log(n), // this function doesn't run 12 Err: () => console.log(`No value`), // this runs 13})
isJust returns a boolean representing the type of the Maybe. If the Maybe is a Just type then true is returned, if it's a Nothing, returns false.
1import { Just, Nothing } from "pratica" 2 3const isOver6Feet = (height) => (height > 6 ? Just(height) : Nothing) 4 5isOver6Feet(7).isJust() // true 6isOver6Feet(4).isJust() // false
isNothing returns a boolean representing the type of the Maybe. If the Maybe is a Just type then false is returned, if it's a Nothing, returns true.
1import { Just, Nothing } from "pratica" 2 3const isOver6Feet = (height) => (height > 6 ? Just(height) : Nothing) 4 5isOver6Feet(7).isNothing() // false 6isOver6Feet(4).isNothing() // true
value returns the encapsulated value within the Maybe. If the Maybe is a Just type, then the arg
is returned, otherwise, if it is a Nothing, then it returns undefined.
1import { Just, Nothing } from "pratica" 2 3const isOver6Feet = (height) => (height > 6 ? Just(height) : Nothing) 4 5isOver6Feet(7).value() // 7 6isOver6Feet(4).value() // undefined
Use this when dealing with conditional logic. Often a replacment for if statements - or for simplifying complex logic trees. A Result can either be an Ok
or an Err
type.
1import { Ok, Err } from "pratica" 2 3const person = { name: "jason", age: 4 } 4 5Ok(person) 6 .map((p) => p.name) 7 .cata({ 8 Ok: (name) => console.log(name), // 'jason' 9 Err: (msg) => console.error(msg), // this func does not run 10 })
1import { Ok, Err } from "pratica" 2 3const person = { name: "Jason", age: 4 } 4 5const isPerson = (p) => (p.name && p.age ? Ok(p) : Err("Not a person")) 6 7const isOlderThan2 = (p) => (p.age > 2 ? Ok(p) : Err("Not older than 2")) 8 9const isJason = (p) => (p.name === "jason" ? Ok(p) : Err("Not jason")) 10 11Ok(person) 12 .chain(isPerson) 13 .chain(isOlderThan2) 14 .chain(isJason) 15 .cata({ 16 Ok: (p) => console.log("this person satisfies all the checks"), 17 Err: (msg) => console.log(msg), // if any checks return an Err, then this function will be called. If isPerson returns Err, then isOlderThan2 and isJason functions won't even execute, and the err msg would be 'Not a person' 18 })
You can also modify errors that may return from any result before getting the final result, by using .mapErr
or .chainErr
.
1import { Err } from "pratica" 2 3Err("Message:") 4 .mapErr((x) => x + " Syntax Error") 5 .map((x) => x + 7) // ignored because it's an error 6 .cata({ 7 Ok: (x) => console.log(x), // function not ran 8 Err: (x) => console.log(x), // 'Message: Syntax Error' 9 })
1import { Err } from "pratica" 2 3Err("Message:") 4 .chainErr((x) => x + Err(" Syntax Error")) 5 .map((x) => x + 7) // ignored because it's an error 6 .cata({ 7 Ok: (x) => console.log(x), // function not ran 8 Err: (x) => console.log(x), // 'Message: Syntax Error' 9 })
Use .swap()
to convert an Err to an Ok, or an Ok to an Err.
1import { Ok } from "pratica" 2 3Ok("hello") 4 .swap() 5 .cata({ 6 Ok: () => console.log(`doesn't run`), 7 Err: (x) => expect(x).toBe("hello"), // true 8 })
Use .bimap()
for easily modifying an Ok or an Err. Shorthand for providing both .map
and .mapErr
1import { Ok } from "pratica" 2 3Ok("hello") 4 .bimap( 5 (x) => x + " world", 6 (x) => x + " goodbye", 7 ) 8 .cata({ 9 Ok: (x) => expect(x).toBe("hello world"), // true 10 Err: () => {}, 11 }) 12 13Err("hello") 14 .bimap( 15 (x) => x + " world", 16 (x) => x + " goodbye", 17 ) 18 .cata({ 19 Ok: () => {}, 20 Err: (x) => expect(x).toBe("hello goodbye"), // true 21 })
1import { Ok } from "pratica" 2 3// Need something like this 4// Ok(6) + Ok(7) = Ok(13) 5Ok((x) => (y) => x + y) 6 .ap(Ok(6)) 7 .ap(Ok(7)) 8 .cata({ 9 Ok: (result) => console.log(result), // 13 10 Err: () => console.log(`This function won't run`), 11 }) 12 13Ok(null) // no function to apply 14 .ap(Ok(6)) 15 .ap(Ok(7)) 16 .cata({ 17 Ok: () => console.log(`This function won't run`), 18 Err: () => console.log(`This function runs`), 19 })
1import { Ok, Err } from "pratica" 2 3Ok(86).inspect() // `Ok(86)` 4Ok("HELLO").inspect() // `Ok('HELLO')` 5Err("Something happened").inspect() // `Err('Something happened')` 6Err(404).inspect() // `Err(404)`
1import { Ok, Err } from "pratica" 2 3const isOver6Feet = (person) => (person.height > 6 ? Ok(person.height) : Err("person is not over 6 feet")) 4 5isOver6Feet({ height: 4.5 }) 6 .map((h) => h / 2.2) 7 .cata({ 8 Ok: (h) => console.log(h), // this function doesn't run 9 Err: (msg) => console.log(msg), // `person is not over 6 feet` 10 })
toMaybe is used for easily converting Result's to Maybe's. Any Result that is an Ok will be converted to a Just with the same value inside, and any value that was Err will be converted to a Nothing with no value passed. The cata will have to include Just
and Nothing
instead of Ok
and Err
.
1import { Ok, Err } from "pratica" 2 3Ok(8) 4 .toMaybe() 5 .cata({ 6 Just: (n) => console.log(n), // 8 7 Nothing: () => console.log(`No value`), // this function doesn't run 8 }) 9 10Err(8) 11 .toMaybe() 12 .cata({ 13 Just: (n) => console.log(n), // this function doesn't run 14 Nothing: () => console.log(`No value`), // this runs 15 })
1import { Ok, Err } from "pratica" 2 3const isOver6Feet = (height) => (height > 6 ? Ok(height) : Err("Shorty")) 4 5isOver6Feet(7).isOk() // true 6isOver6Feet(4).isOk() // false
1import { Ok, Err } from "pratica" 2 3const isOver6Feet = (height) => (height > 6 ? Ok(height) : Err("Shorty")) 4 5isOver6Feet(7).isErr() // false 6isOver6Feet(4).isErr() // true
Returns either the value contained in the Ok, or the error in the Err
1import { Ok, Err } from "pratica" 2 3const six = Ok(6).value() 4const error = Err("Something happened").value() 5 6console.log(six) // 6 7console.log(error) // 'Something happened'
Safely parse date strings. parseDate returns a Maybe monad.
1import { parseDate } from "pratica" 2 3const goodDate = "2019-02-13T21:04:10.984Z" 4const badDate = "2019-02-13T21:04:1" 5 6parseDate(goodDate).cata({ 7 Just: (date) => expect(date.toISOString()).toBe(goodDate), 8 Nothing: () => console.log("could not parse date string"), // this function doesn't run 9}) 10 11parseDate(badDate).cata({ 12 Just: () => console.log(`this function doesn't run`), 13 Nothing: () => "this function runs", 14}) 15 16// it's a maybe, so you can use chain/default/ap 17parseDate(null) 18 .default(() => new Date()) 19 .cata({ 20 Just: (date) => date.toISOString(), // this runs 21 Nothing: () => `doesn't run because of the .default()`, 22 })
Safely run functions that may throw an error or crash. encase returns a Maybe type (so Just or Nothing).
1import { encase } from "pratica" 2 3const throwableFunc = () => JSON.parse("<>") 4 5// this func doesn't throw, so Just is called 6encase(() => "hello").cata({ 7 Just: (x) => console.log(x), // hello 8 Nothing: () => console.log("func threw error"), // this func doesn't run 9}) 10 11// this function throws an error so Nothing is called 12encase(throwableFunc).cata({ 13 Just: (json) => console.log(`doesn't run`), 14 Nothing: () => console.error("func threw an error"), // this runs 15})
Safely run functions that may throw an error or crash. encaseRes returns a Result type (so Ok or Err). Similar to encase
but the Err returns the error message.
1import { encaseRes } from "pratica" 2 3const throwableFunc = () => JSON.parse("<>") 4 5// this func doesn't throw, so Ok is called 6encaseRes(() => "hello").cata({ 7 Ok: (x) => console.log(x), // hello 8 Err: () => console.log("func threw error"), // this func doesn't run 9}) 10 11// this function throws an error so Err is called 12encaseRes(throwableFunc).cata({ 13 Ok: (json) => console.log(`doesn't run`), 14 Err: (msg) => console.error(msg), // SyntaxError: Unexpected token < in JSON at position 0 15})
Filter out any non-Just data type from an array
1import { justs } from "pratica" 2 3const data = [1, true, Just("hello"), Nothing, Ok("hey"), Err("No good")] 4 5justs(data) // returns [Just('hello')]
Filter out any non-Ok data type from an array
1import { oks } from "pratica" 2 3const data = [1, true, Just("hello"), Nothing, Ok("hey"), Err("No good")] 4 5oks(data) // returns [Ok('hey')]
Safely retrieve a nested property in an object. Returns a Maybe.
1import { get } from "pratica" 2 3const data = { 4 name: "jason", 5 children: [ 6 { 7 name: "bob", 8 }, 9 { 10 name: "blanche", 11 children: [ 12 { 13 name: "lera", 14 }, 15 ], 16 }, 17 ], 18} 19 20get(["children", 1, "children", 0, "name"])(data).cata({ 21 Just: (name) => expect(name).toBe("lera"), // true 22 Nothing: () => console.log("no name"), // doesn't run 23})
Safely get the first item in an array. Returns a Maybe.
1import { head } from "pratica" 2 3const data = [5, 1, 2] 4 5// example with data 6head(data).cata({ 7 Just: (x) => expect(x).toBe(5), // true, 8 Nothing: () => console.log("No head"), // won't run 9}) 10 11// example with empty data 12head([]).cata({ 13 Just: (x) => console.log(x), // doesn't run 14 Nothing: () => console.log("No head"), // runs 15})
Safely get the last item in an array. Returns a Maybe.
1import { last } from "pratica" 2 3const data = [5, 1, 2] 4 5// example with data 6last(data).cata({ 7 Just: (x) => expect(x).toBe(2), // true, 8 Nothing: () => console.log("No last"), // won't run 9}) 10 11// example with empty data 12last([]).cata({ 13 Just: (x) => console.log(x), // doesn't run 14 Nothing: () => console.log("No last"), // runs 15})
Safely get the tail of an array (Everything except the first element). Returns a Maybe.
1import { tail } from "pratica" 2 3const data = [5, 1, 2] 4 5// example with data 6tail(data).cata({ 7 Just: (x) => expect(x).toEqual([1, 2]), // true, 8 Nothing: () => console.log("No tail"), // won't run 9}) 10 11// example with empty data 12last([]).cata({ 13 Just: (x) => console.log(x), // doesn't run 14 Nothing: () => console.log("No tail"), // runs 15})
Safely try to retrieve an item from an array. Returns a Maybe.
1import { tryFind } from "pratica" 2 3const users = [ 4 { name: "jason", age: 6, id: "123abc" }, 5 { name: "bob", age: 68, id: "456def" }, 6] 7 8tryFind((u) => u.id === "123abc")(users).cata({ 9 Just: (user) => expect(user).toEqual(users[0]), // true 10 Nothing: () => "Could not find user with id 123abc", // doesn't run 11})
Safely collect values from an array of results. Returns a result.
1import { collectResult } from "pratica" 2 3const all_good = [Ok(1), Ok(2), Ok(3)] 4const one_bad = [Ok(1), Err("Some error"), Ok(3)] 5 6collectResult(all_good).cata({ 7 Ok: (x) => expect(x).toEqual([1, 2, 3]), // true 8 Err: () => "no values", // doesn't run 9}) 10 11collectResult(one_bad).cata({ 12 Ok: (x) => x, // doesn't run 13 Err: (err) => expect(err).toEqual("Some error"), // true 14})
Safely collect values from an array of maybes. Returns a maybe.
1import { collectMaybe } from "pratica" 2 3const all_good = [Just(1), Just(2), Just(3)] 4const one_bad = [Just(1), Nothing, Just(3)] 5 6collectMaybe(all_good).cata({ 7 Just: (x) => expect(x).toEqual([1, 2, 3]), // true 8 Nothing: () => "no values", // doesn't run 9}) 10 11collectMaybe(one_bad).cata({ 12 Just: (x) => x, // doesn't run 13 Nothing: () => "no values", // true 14})
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
0 existing vulnerabilities detected
Reason
Found 7/26 approved changesets -- score normalized to 2
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
security policy file not detected
Details
Reason
project is not fuzzed
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2025-07-07
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More