Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

What is the idiomatic way to do pattern matching in the fp-ts ecosystem #1892

Open
CarpentersKeys opened this issue Jul 24, 2023 · 7 comments

Comments

@CarpentersKeys
Copy link

Hi I'm pretty new to fp concepts but I'm starting to work on some demos with the library

I want to do something like

interface ICounterActions {type: "increment" | "decrement"}
const counterReducer = (state: number, action: ICounterActions) => {
  return pipe(
    { state, ...action },
    match<ICounterActions>("type")({
      increment: state => state + 1,
      decrement: state => state - 1,
      a: () => {}, // would like compile error
    })
  );
};

is there a way of doing this with fo-ts alone? I browsed through the modules several times but I could be missing it because I don't know a term.

is there a recommended library?

I realize I could just use switch but it's not pipeable.

Thanks in advance.

@gcanti
Copy link
Owner

gcanti commented Jul 24, 2023

There's no module in fp-ts for generic pattern matching, all data types have its own specialized match function, you can use something like ts-pattern

@CarpentersKeys
Copy link
Author

Would it make sense to have Record.match to do this?

Would also like the options to match("key")([predicate, operation])(value)

@DenisFrezzato
Copy link
Collaborator

Perhaps https://github.com/pfgray/ts-adt is more close to what you're looking for.

@siwatanejo
Copy link

all data types have its own specialized match function, you can use something like ts-pattern

Can you give an example? I'm finding very hard to use fp-ts from TS (mind you, I don't have zero FP experience, I come from F#).

@samhh
Copy link
Contributor

samhh commented Sep 13, 2023

There's also @unsplash/sum-types if you can accept the constraint of no generics.

@kingjordan
Copy link

I use ts-adt like @DenisFrezzato mentioned

use it like:

import { makeMatch } from "ts-adt/MakeADT";

interface ICounterActions {type: "increment" | "decrement"}
 matchType = makeMatch("type");

const counterReducer = (state: number, action: ICounterActions) => {
  return pipe(
    action,
    matchType({
      increment: ()=> { state => state + 1 },
      decrement: ()=> { state => state - 1 },
   })
};

This will throw an error if have not implemented a type or implement a type that does not exist. I personally like this because if I make a change it forces me to handle the new type anywhere I match it.

This video explains it well

@siwatanejo
Copy link

Holy shit that's ugly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants