Functional programming: driving team adoption
Introducing functional programming within a team could be a challenge: there are new concepts and terminology to grasp. What I'm experimenting with is to simplify. As an example, let's take Either
from fp-ts:
- Instead of
Left
andRight
, we can use familiar terminology such asResult
,Success
, andFailure
- Instead of bringing a big complex library, we can reimplement a small part and make it easy to understand for others
And then hunt for a good use-case, where we can demonstrate the added value. Here's how the code could look like:
// spec
describe("Result", () => {
it("should work for success", () => {
const r = success("foo")
expect(isSuccess(r)).toBeTruthy()
expect(isFailure(r)).toBeFalsy()
expect(isSuccess(r) && r.value).toEqual("foo")
})
it("should work for a failure", () => {
const r = failure({ reason: "bar" })
expect(isSuccess(r)).toBeFalsy()
expect(isFailure(r)).toBeTruthy()
expect(isFailure(r) && r.error).toEqual({ reason: "bar" })
})
})
// implementation
export interface Failure<E> {
readonly _tag: "Failure"
readonly error: E
}
export interface Success<A> {
readonly _tag: "Success"
readonly value: A
}
export type Result<E, A> = Failure<E> | Success<A>
export const success = <A>(a: A): Result<never, A> => ({
_tag: "Success",
value: a,
})
export const failure = <E>(e: E): Result<E, never> => ({
_tag: "Failure",
error: e,
})
export const isFailure = <E>(r: Result<E, unknown>): r is Failure<E> =>
r._tag === "Failure"
export const isSuccess = <A>(r: Result<unknown, A>): r is Success<A> =>
r._tag === "Success"
- ← Previous post: AWS Athena: Adding yyyy/mm/dd partitions to an S3 table
- → Next post: Passing a secret value to AWS Lambda
This blog is written by Marcel Krcah, an independent consultant for product-oriented software engineering. If you like what you read, sign up for my newsletter