question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. ItĀ collects links to all the places you might be looking at while hunting down a tough bug.

And, if youā€™re still stuck at the end, weā€™re happy to hop on a call to see how we can help out.

`bindTo` messes up the monadic index

See original GitHub issue

šŸ› Bug report

bindTo messes up the monadic index. For example, consider a broader monadic index that takes you through AuthenticationOpen to AuthorizationOpen and then StatusOpen and so forth.

authentication middleware:

declare const authenticate: Middleware<AuthenticationOpen, AuthorizationOpen, unknown, AuthenticatedUser>

one of many authorization middlewares

declare const userHasReadAccess: (u:AuthenticatedUser) => Middleware<AuthorizationOpen, StatusOpen, unknown, AuthorizedUser>

const myController = pipe(
  authenticate,
  H.ichain(userHasReadAccess),
  H.bindTo('user'), // <-- property AuthenticationOpen is missing in type StatusOpen . . .
  H.bind('query', () => H.decodeQuery(/* . . . */)),
  /* . . . */

bindTo takes Middleware<I,I,E,A> and returns Middleware<I,I,E,{ ... }> but it should take Middleware<I,O,E,A> because not every middleware passed into bindTo will have the same "inā€™ and ā€œoutā€ index.

Your environment

Which versions of hyper-ts are affected by this issue? Did this work in previous versions of hyper-ts?

Software Version(s)
fp-ts 2.10.5
hyper-ts 0.6.5
TypeScript 3.9.2

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
DenisFrezzatocommented, Jun 27, 2021

can you clarify the difference between bind and ibind then?

Itā€™s the same difference between chain and ichain (since bind is just a utility around chain). ichain is the indexed version of chain, which additionally updates the indexes.

honestly I only ever use ichain and never chain

You should use chain when the operation doesnā€™t change the indexes.

import * as H from 'hyper-ts'
import * as M from 'hyper-ts/lib/Middleware'
import { pipe } from 'fp-ts/function'
import * as t from 'io-ts'


declare function sendStatus<E>(
  status: H.Status,
): M.Middleware<H.StatusOpen, H.ResponseEnded, E, void>

const ReqBody = t.type({ name: t.string })

const userHandler = pipe(
  M.decodeBody(ReqBody.decode),
  // Chain a new Middleware, same indexes.
  M.chain((user) => user.name === 'Denis' ? M.right(user) : M.left('Wrong name')),
  // Chain a new Middleware with different indexes.
  M.ichain(() => sendStatus(H.Status.NoContent)),
  M.orElse(() => sendStatus(H.Status.BadRequest))
)

Also, Iā€™ll do a PR for map.

map is fine, we need an indexed version imap for that too, see https://hackage.haskell.org/package/indexed-0.1.3/docs/Data-Functor-Indexed.html or https://pursuit.purescript.org/packages/purescript-indexed-monad.

0reactions
kylegoetzcommented, Jul 11, 2021

@DenisFrezzato Iā€™m closing my issue since it appears youā€™ve implemented this in a forthcoming version.

Read more comments on GitHub >

github_iconTop Results From Across the Web

haskell - What is a monad? - Stack Overflow
A monad is a function composition technique that externalizes treatment for some input scenarios using a composing function, bind , to pre-process inputĀ ......
Read more >
Haskell: Strictness and the monadic bind - Mark Needham
From my observations it would seem that the IOArray is one of those monads which evaluates bind strictly. I tried looking at the...
Read more >
On Monads - Wiki
Simply, monads are wrappers around function invocations. They're a lot like like C++ ->() operators. They're also a lot like interceptors inĀ ...
Read more >
Monad Factory: Type-Indexed Monads - Mark H. Snyder
ā€“ Type-indexed monads are compatible with existing monadic code, so we do not have to prepare our existing code to accomodate type-indexed monads....
Read more >
Monads as containers - HaskellWiki
A monad is a container type together with a few methods defined on it. Monads model different kinds of computations.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found