Comments (9)
Hi! Yes, I believe these are applicatives.
so if I look for instance at your crocks link:
// add :: Number -> Number -> Number
const add =
x => y => x + y
Maybe.of(add)
.ap(Just(5))
.ap(Just(27))
//=> Just 32
It seemed to me that the 'lift' approach is easier to handle with typescript (but this can be discussed). So one way to express this same thing in prelude today is like that:
const lifted = Option.liftA2((x:number,y:number) => x+y);
lifted(Option.of(5), Option.of(6));
=> Option.of(11)
const lifted2 = Option.liftA2((x:number,y:number) => x+y);
lifted2(Option.of(5), Option.none<number>());
=> Option.none()
For that specific use-case we achieve the same outcome.
liftA2 is obviously limited to only two parameters. For more, there is liftAp.
const lifted = Option.liftAp((x:{a:number,b:number,c:number}) => x.a+x.b+x.c);
lifted({a:Option.of(5), b:Option.of(6), c:Option.of(3)});
=> Option.of(14)
The lift functions are also available for other functors, like Either and so on.
As per your research, it seems that the ap
approach is really seeing more adoption. I'm not sure whether the difference is only ergonomics or whether it also has other advantages. I think at the time I picked the lift approach also because I thought the ap
type signature could be messy. This could be revisited potentially.
from prelude-ts.
I'm not an expert on ADTs, but I am used to seeing things like ap
and chain
, which seem to be similar to lift
but not quite the same.
I found this from some googling:
When "lift" is referred to as a function, though, it's just a variation of map, ap, or chain that takes the function argument first, and returns a new function that takes the functor value and maps/aps/chains on it. That is, given the map-equivalent version of lift, arg.map(f) is identical to lift(f)(arg). Lifting the function, rather than using map directly, makes it easier to pass the function around and apply it to other values, as it lets you use normal function-call syntax, passing arguments, rather than having to specially use the map method.
I'll keep doing some more digging and see if I can do what I want with lift
, but it might be good to include alternate ways of doing things, or at least documenting the differences.
from prelude-ts.
I think I was able to wrap my head around how to use lift
to replace ap
, but it has brought something else to my attention.
Consider this workflow (using crocks):
import Maybe from 'crocks/Maybe'
// define two people, one with a defined age and one without
const personOne = Maybe.of({
name: 'Bob',
})
const personTwo = Maybe.of({
name: 'Jane',
age: '33'
})
// this function returns Just the age or Nothing
const getAge = x =>
x.age ? Maybe.Just(x.age) : Maybe.Nothing()
// get the age and log it, or log that age is not defined
const logAge = x =>
x.chain(getAge)
.coalesce(
() => console.log('age is not defined'),
console.log
)
logAge(personOne)
// age is not defined
logAge(personTwo)
// 33
This is a pretty common pattern for me (I use it for rendering a react component if data exists, or rendering an empty state).
Without chain
or coalesce
I am not sure how to go about creating this flow using prelude-ts
.
Perhaps this is a different way of thinking that doesn't line up with prelude-ts
.
Since I am expanding the scope of my issue, should I rename or change this issue into something else?
from prelude-ts.
I think instead of chain
you want prelude's flatMap
and instead of coalesce
you want.. well if you want to return something, you'd use getOrElse
or getOrCall
. If you just want the side-effect in case the option is not present you'd use ifNone
.
The concepts are mostly the same, it's just one style or the other I think.
from prelude-ts.
Ah, that makes sense.
Here is what I've come up with:
import { Option } from 'prelude-ts'
const { log } = console
const personOne = Option.of({
name: 'Bob',
})
const personTwo = Option.of({
name: 'Jane',
age: '33'
})
const getAge = (x: { age?: number }) =>
x.age ? Option.some(x.age) : Option.none()
const logAge = (x: Option<any>) =>
x.flatMap(getAge)
.ifNone(() => console.log('age is not defined'))
.map(log)
logAge(personOne)
// age is not defined
logAge(personTwo)
// 33
Is there a language or source for the inspiration of prelude-ts
that could help me understand?
from prelude-ts.
Prelude-ts is inspired by the vavr Java library, itself inspired by the Scala language.
Did you see the prelude user guide?
from prelude-ts.
I did take a look through that guide. I can try and wrap my head around Scala better, but I'm not sure I'd be able to sell prelude-ts
to a team with the current documentation.
I would love to be able to use something like prelude-ts
(adts in TypeScript), but I wish it had the level of documentation of ramda
or crocks
to make it a bit more accessible to people not familiar with Scala.
I'll keep an eye on this library and keep playing around with it, but I am not sure it meets my needs at this point.
from prelude-ts.
No problem! I think it's a matter of which library gives you what you need. What prelude does better than the others, it seems to me, would be on the collections side, especially the proper hashmap with hashing & equality, enabling a proper groupBy for instance, and typescript types (but fp-ts may be even better on that, not sure).
Certainly I would keep this bug open, regarding the ap
feature, that's a good point. I'll try to find some time at some point in the future to think how to implement this in a way that the types work out. It may not be possible though.
In the end, I think the differences here are really more cosmetic, these are all functors, applicatives, monads. So i'm really happy to see that ecosystem of solutions!
from prelude-ts.
I agree about the collections! That is one of the really appealing things to me.
from prelude-ts.
Related Issues (20)
- Replace sed with TS program HOT 3
- make allMatch a type guard as it will be in TS4.0
- add Seq or Vector rotateLeft & rotateRight
- HashMaps comparison always seems to return the same hash code HOT 5
- constant HOT 1
- Allow equality comparer in the Set/Map constructor HOT 3
- Help with preserving order in HashSet HOT 6
- Vite util.inspect HOT 2
- Allow fold to use a different type on the accumulator HOT 3
- Implement sequenceAcc for Option HOT 2
- Tuple2 equality is broken HOT 1
- Make preludeTsContractViolationCb throw an exception instead of a string? HOT 3
- Can areEqual be undefined-safe too? HOT 2
- Validation - accumulating errors with Either HOT 2
- Typo in the docs HOT 1
- Function returned from Either::liftApAcc closes over leftErrs from the outer scope
- HashMap equality calculated incorrectly HOT 14
- Option equality broken HOT 2
- Cannot stringify arbitrary non-POJOs Some. HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from prelude-ts.