DEV Community

Discussion on: Getting started with fp-ts: Reader

Collapse
 
macsikora profile image
Pragmatic Maciej

Yes I see this in that way also. The whole idea here is in dependency argument in the end and not in the beginning.

In my comment I was more addressing the whole additional idealogy over that, like special typings and using some pipe, ask, chain. I see these as only a fog and complexity over really simple but powerful concept.

Thread Thread
 
gcanti profile image
Giulio Canti

There's a benefit in using the monadic interface though: software is written in a uniform style, regardless of the effect.

You can think of Reader as an effect, muck like Either or Task.

Let's say you have the following snippet

import * as E from 'fp-ts/lib/Either'
import { pipe } from 'fp-ts/lib/pipeable'

declare function f(s: string): E.Either<Error, number>
declare function g(n: number): boolean
declare function h(b: boolean): E.Either<Error, Date>

// composing `f`, `g`, and `h` -------------v---------v-----------v
const result = pipe(E.right('foo'), E.chain(f), E.map(g), E.chain(h))

const pointFreeVersion = flow(f, E.map(g), E.chain(h))
Enter fullscreen mode Exit fullscreen mode

and at some point you must refactor f to

import * as RE from 'fp-ts/lib/ReaderEither'

interface Dependencies {
  foo: string
}

declare function f(s: string): RE.ReaderEither<Dependencies, Error, number>
Enter fullscreen mode Exit fullscreen mode

result and pointFreeVersion must be refactored as well, fortunately you can use ReaderEither's monadic interface

// before 
const result = pipe(E.right('foo'), E.chain(f), E.map(g), E.chain(h))

const pointFreeVersion = flow(f, E.map(g), E.chain(h))

// after
const result = pipe(
  RE.right('foo'),
  RE.chain(f),
  RE.map(g),
  RE.chain(b => RE.fromEither(h(b)))
)

const pointFreeVersion = flow(
  f,
  RE.map(g),
  RE.chain(b => RE.fromEither(h(b)))
)
Enter fullscreen mode Exit fullscreen mode
Thread Thread
 
vicrac profile image
Michał Kaczanowicz

There's a benefit in using the monadic interface though: software is written in a uniform style, regardless of the effect.

I was just about to say it: I think main benefit is (ironically) readability - by saying explicitly Reader<Dependencies, string> you clearly communicate your intent (assuming others know the concept as well, of course 😄).

Thread Thread
 
gcanti profile image
Giulio Canti

That's right, you write programs by composing kleisli arrows A -> M<B>, for some effect M.

So Reader (or ReaderEither, ReaderTaskEither, Option, Either, etc...) is just one of the possible effects