Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
exalted.future
Advanced tools
Exalted monadic library & functional fun, fantasy-land compliant, mostly.
A javascript and typescript monadic library & functional fun. fantasy-land compliant, mostly.
The style of monad object is inspired by DrBoolean course on egghead.io.
The choice for cata
, encase
, head
, tail
, last
is inspired by rametta's take on monads in pratica.
This is, in many ways, an evolution of oncha which I wrote with other people many years ago and is no longer maintained.
yarn add exalted.future
Name | Apply | Applicative | Setoid | Foldable | Functor | Monad | Chain |
---|---|---|---|---|---|---|---|
Either | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ |
Future | ✔︎ | — | ✔︎ | ✔︎ | ✔︎ | — | ✔︎ |
Identity | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ |
Maybe | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ | ✔︎ |
reduce
is named cata
and loosely based on daggy's union types.fold
always folds on identity a => a
, except when it does not like with the Future
.Maybe.map
will return Nothing if the callback function returns null. In other words Just(null)
is impossible, unless you call the 'static' constructor like this Just.of(null)
. See this pr for some explanation.These functions are available on all types.
chain :: (a -> b) -> b
Id(5).chain(a => Id(a))
//=> Id(5)
// You can use chain to join the monads.
Id(Id(5)).chain(a => a)
//=> Id(5)
equals :: Id -> Boolean
Id(1).equals(Id(1))
//=> true
Id(2).equals(Id(1))
//=> false
Id(2).equals(Id(1)) === Id(1).equals(Id(1))
//=> false
chain :: (a -> b) -> b
Id(5).chain(a => Id(a))
//=> Id(5)
// You can use chain to join the monads.
Id(Id(5)).chain(a => a)
//=> Id(5)
map :: (a -> b) -> Id of b
Id(7).map(a => a * 2)
//=> Id(14)
of :: a -> Id of a
Id(5).of(6)
//=> Id(6)
Id(5).of(Id(6))
//=> Id(Id(6))
fold :: (a -> b) -> b
Id(5).fold()
//=> 5
Id(5).fold()
//=> 6
cata :: ({ Left: () -> b, Right -> a -> a }) -> a | b
Id(5).cata({
Right: a => a
})
//=> 5
Id(5).cata({
Right: a => a + 1
})
//=> 6
Right(5).cata({
Left: a => 8 // ignored
Right: a => a + 1
})
//=> 6
Left(5).cata({
Left: a => a + 1
Right: a => 8 // ignored
})
//=> 6
inspect :: () -> String
Id(5).inspect()
//=> Id(5)
Identity monad.
Id(5)
.map(num => num * 7)
.map(num => num - 1)
.cata({
Right: a => a
})
//=> 34
Maybe monad.
// Maybe of a string
Maybe('Hello exalted one')
.map(sentence => sentence.toUpperString())
.map(sentence => `${sentence}!`)
.cata({
Right: console.log
})
//=> 'HELLO EXALTED ONE!'
// Maybe of nothing
Maybe(null)
.map(sentence => sentence.toUpperString())
.alt(() => 'Maybe received a null')
.cata({
Right: console.log
})
//=> 'Maybe received a null'
Sets the value to cata on.
alt :: Any -> Nothing of Any
Maybe(1).alt(5).cata({
Right: a => a
})
//=> 1
Maybe(null).alt(5).cata({
Right: a => a
})
//=> 5
cata :: ({ Left: () -> b, Right: a -> b }) -> a|b
Maybe(5).cata({
Right: a => a
})
//=> 5
Maybe(5).cata({
Left: () => { } // not called
Right: a => a + 1
})
//=> 6
Maybe(null).cata({
Left: () => 'there was a null'
Right: a => a + 1 // not called
})
//=> there was a null
An Either monad and nullable, Left, Right.
nullable('Hello') // this will return a Right('Hello')
.cata({
Left: () => 'Oops',
Right: val => `${val} world!`
})
//=> 'Hello world!'
nullable(null) // this will return a Left()
.cata({
Left: () => 'Oops',
Right: val => `${val} world!`
})
//=> 'Oops'
const extractEmail = obj => obj.email ? Right(obj.email) : Left()
extractEmail({ email: 'test@example.com' }
.map(extractDomain)
.cata({
Left: () => 'No email found!',
Right:x => x
})
//=> 'example.com'
extractEmail({ name: 'user' }
.map(extractDomain) // this will not get executed
.cata({
Left: () => 'No email found!',
Right: x => x
})
//=> 'No email found!'
Foldable - Folds foldable object.
cata :: ({ Left: () -> b, Right -> a -> a }) -> a | b
Right(5).cata({
Left: () => 1,
Right: a => a + 2
})
//=> 7
Left(5).cata(a => a + 1)
//=> 6
A Future monad for async computation.
// Basic usage
Future((reject, resolve) => resolve('Yay'))
.map(res => res.toUpperString())
.fork(
err => log(`Err: ${err}`),
res => log(`Res: ${res}`))
//=> 'YAY'
// Handle promises
Future.promise(fetch('https://api.awesome.com/catOfTheDay'))
.fork(
err => log('There was an error fetching the cat of the day :('),
cat => log('Cat of the day: ' + cat))
//=> 'Cat of the day: Garfield'
// Chain http calls
Future.promise(fetch('https://api.awesome.com/catOfTheDay'))
.chain(cat => Future.promise(fetch(`https://api.catfacts.com/${cat}`)))
.fork(
err => log('There was an error fetching the cat of the day :('),
facts => log('Facts for cat of the day: ' + facts))
//=> 'Facts for cat of the day: Garfield is awesome.'
Forks all the futures.
all :: ([Futures]) -> b
Future.all(
Future.of('apple'),
Future((left, right) => setTimeout(() => right('orange'), 1000)),
Future.of('lemon')
).fork(
() => (),
([ apple, orange, lemon ]) =>
//=> apple, orange, lemon
)
Foldable Folds on identity.
fold :: (a -> b) -> b
Future.of(5).fold()
//=> 5
Executes the Future
returning a Future
of the resuts.
fork :: (a -> a, b -> b) -> Future of a | b
Future((left, right) => right(5)).fork(a => a, a => a)
//=> Future of 5
Future((left, right) => left(Error('this is an error'))).fork(a => a)
//=> Future of Error
Compose takes n functions as arguments and return a function.
const transform = compose(sentence => sentence.toUpperString(), sentence => `${sentence}!`)
const logTransform = compose(log, transform)
logTransform('Hello exalted one')
//=> 'HELLO EXALTED ONE!'
// supports miltiple arguments
compose(path.normalize, path.join)('./exalted', '/one')
//=> './exalted/one'
Map as partial application and first class with arity support.
map(a => a + 1, a => a * 3)([1, 2, 3])
//=> [4, 7, 10]
Returns a Maybe.
head([1,2])
//=> Just(1)
head([])
//=> Nothing()
tail([1,2,3])
//=> Just([2,3])
tail([])
//=> Nothing()
last([1,2,3])
//=> Just(3)
last([])
//=> Nothing()
Returns Left | Right
.
encase(() => JSON.parse('["foo","bar","baz"]'))
//=> Just(['foo','bar','baz'])
encase(() => JSON.parse('['))
//=> Nothing()
encaseEither(() => JSON.parse('["foo","bar","baz"]'))
//=> Right(['foo','bar','baz'])
encaseEither(() => JSON.parse('['))
//=> Left(new SyntaxError ('Unexpected end of JSON input'))
FAQs
Exalted monadic library & functional fun, fantasy-land compliant, mostly.
The npm package exalted.future receives a total of 1 weekly downloads. As such, exalted.future popularity was classified as not popular.
We found that exalted.future demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.