Skip to content
This repository has been archived by the owner. It is now read-only.
This repository has been archived by the owner. It is now read-only.

Problems with Router (Kleisli vs PartialFunction) #288

@vegansk

Description

@vegansk

The first problem is that PartialFunction doesn't compose well. Example:

@ val f1: PartialFunction[Int, Int] = { case 1 => 2 }
f1: PartialFunction[Int, Int] = <function1>

@ val f2: PartialFunction[Int, Int] = { case 1 => 3 }
f2: PartialFunction[Int, Int] = <function1>

@ f1.andThen(f2)
res2: PartialFunction[Int, Int] = <function1>

@ res2.isDefinedAt(1)
res3: Boolean = true

@ res2(1)
scala.MatchError: 2 (of class java.lang.Integer)
  ...

And this leads us to the problem. I want to log the state before and after toState call. Of cause I can write it directly, but what is FP for? :-) I want to do is as middleware and compose it. Maybe it's better to use Kleisli with OptionT here? It composes well.

The Second problem again with PartialFunction and toState. The signature of the function is PartialFunction[Router.Path, S => F[S]]. And if I want to make a decision about handling the path based on the old state, I just can't do it in the pattern matching. All I can do is to return the old state.

What if change Router definition like this?

final case class Router[F[_]: Async, S](
    fromState: Kleisli[Option, S, Router.Path] = ???
    toState: Kleisli[OptionT[F, *], (Router.Path, S), S] = ???
)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions