1

I am trying to create a map that can convert the input type of a function to another type. Normally when we map, we have a function A => B, but since we are mapping the inputs in functions, I believe this means we actually need a function B => A, as in the following:

  enum Result[+V, +E, +A]:
    case View(view: V)
    case Eff(eff: IO[E, Unit])
    case Res(result: A, remaining: Unit => Any)
  object Result {
    def map[A,B,V,E](fn: A => B)(res: Result[V,E,A]): Result[V,E,B] = res match {
      case View(v) => View(v)
      case Eff(e) => Eff(e)
      case Res(res, rem) => Res(fn(res), rem)
    }
  }
  type ResultRun[V,E,A] = Result[V, E, A] => IO[E, Unit]
  object ResultRun {
    // f: A -> C
    // fn: B -> A
    // fn andThen f : B -> C
    def map[V,E,A,B](fn: B => A)(rr: ResultRun[V,E,A]): ResultRun[V,E,B] = Result.map(fn).andThen(rr)
  }

This results in the following type error, which likely indicates I'm doing something wrong that is more fundamental than indicated by the error:

[error] 50 |    def map[V,E,A,B](fn: B => A)(rr: ResultRun[V,E,A]): ResultRun[V,E,B] = Result.map(fn).andThen(rr)
[error]    |                                                                                                  ^^
[error]    |Found:    (rr : concur.Types.ResultRun[V, E, A])
[error]    |Required: concur.Types.Result[Any, Any, A] => IO[E, Unit]
[error]    |
[error]    |One of the following imports might make progress towards fixing the problem:
[error]    |
[error]    |  import scalajs.js.Any.fromFunction1
[error]    |  import scalajs.js.ThisFunction.fromFunction1

Also, maybe this should be called contraMap, instead of map.

1 Answer 1

1

Where is the IO in case Eff(eff: IO[E, Unit]) come from ?

The following code compiles if I defined IO as case class IO[+X, -Y]():

  enum Result[+V, +E, +A]:
    case View(view: V)
    case Eff(eff: IO[E, Unit])
    case Res(result: A, remaining: Unit => Any)
  object Result {
    def map[A,B,V,E](fn: A => B)(res: Result[V,E,A]): Result[V,E,B] = res match {
      case View(v) => View(v)
      case Eff(e) => Eff(e)
      case Res(res, rem) => Res(fn(res), rem)
    }
  }
  type ResultRun[V,E,A] = Result[V, E, A] => IO[E, Unit]
  object ResultRun {
    // f: A -> C
    // fn: B -> A
    // fn andThen f : B -> C
    def map[V,E,A,B](fn: B => A)(rr: ResultRun[V,E,A]): ResultRun[V,E,B] = Result.map[B, A, V, E](fn).andThen(rr)
  }
Sign up to request clarification or add additional context in comments.

1 Comment

Interesting, I see - this is coming from the ZIO library, so I think in my case it should be IO[+E, +A], as either an E or an A might be produced from IO values.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.