Wednesday, 30 November 2022

Convert type `(env) => (args) => TaskEither` to ReaderTaskEither

In my SPA, I have a function that needs to:

  1. Create an object (e.g. a "tag" for a user)
  2. Post it to our API
type UserId = string;
type User = {id: UserId};

type TagType = "NEED_HELP" | "NEED_STORAGE"
type Tag = {
  id: string;
  type: TagType;
  userId: UserId;
}
type TagDraft = Omit<Tag, "id">

// ----

const createTagDraft = ({tagType, user} : {tagType: TagType, userId: UserID}): TagDraft => ({
  type: tagType, userId: userId
})

const postTag = (tagDraft) => pipe(
    TE.tryCatch(
      () => axios.post('https://myTagEndpoint', tagDraft),
      (reason) => new Error(`${reason}`),
    ),
    TE.map((resp) => resp.data),
  )

I can combine the entire task with

const createTagTask = flow(createTagDraft, postTag)

Now I would like to also clear some client cache that I have for Tags. Since the cache object has nothing to do with the arguments needed for the tag, I would like to provide it separately. I do:

function createTagAndCleanTask(queryCache) {
  return flow(
    createTagDraft,
    postTag,
    TE.chainFirstTaskK((flag) =>
      T.of(
        queryCache.clean("tagCache")
      )
    )
  )
}

// which I call like this
createTagAndCleanTask(queryCache)({tagType: "NEED_HELP", user: bob})

This works, but I wonder if this is not exactly what I could use ReaderTaskEither for?

Idea 1: I tried to use RTE.fromTaskEither on createTagTask, but createTagTask is a function that returns a TaskEither, not a TaskEither...

Idea 2: I tried to use RTE.fromTaskEither as a third step in the flow after postTag but I don't know how to provide proper typing then and make it aware of a env config object.

My understanding of this article is that I should aim at something like (args) => (env) => body instead of (env) => (args) => body for each functions. But I cannot find a way to invert arguments that are provided directly via flow.

Is there a way that can I rewrite this code so that I can provide env objects like queryCache in a cleaner way?



from Convert type `(env) => (args) => TaskEither` to ReaderTaskEither

No comments:

Post a Comment