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

Implement xmap2Either and Sequence for Config #39

Closed
afsalthaj opened this issue Sep 30, 2019 · 2 comments
Closed

Implement xmap2Either and Sequence for Config #39

afsalthaj opened this issue Sep 30, 2019 · 2 comments
Assignees

Comments

@afsalthaj
Copy link
Collaborator

afsalthaj commented Sep 30, 2019

Possibly include a xmap2Either in config data type, that is a form of invariant applicative functor that handle errors.

In Config type,

  def xmap2Either[B, C](that: Config[B])(f: (A, B) => Either[ReadError, C])(g: C => Either[WriteError, (A, B)]): Config[C] = {
    (self |@| that).apply[(A, B)]((a, b) => (a, b), t => Some((t._1, t._2))).mapEither(b => f(b._1, b._2))(g)
  }


This allows us to implement the following in the companion object

 def sequence[A](list: List[Config[A]]): Config[List[A]] = {
    list.foldLeft(Pure(Nil: List[A]): Config[List[A]])((a, b) => b. xmap2Either(a)((aa, bb) => Right( aa :: bb))(t => Right((t.head, t.tail))))
  }

// where Pure is

  final case class Pure[A](a: A) extends Config[A]

This enables user parse complicated groupings in the env. Although, not a convincing example below, it is essential to make config traversable and allow users to do such things.

final case class Variables(variable1: Int, variable2: Option[Int])

  val listOfConfig: List[Config[Variables]] =
    (0 to 3).toList.map(t => (int(s"${t}_VARIABLE1") |@| opt(int(s"${t}_VARIABLE2")))(Variables.apply, Variables.unapply))

  val configOfList: Config[List[Variables]] =
    Config.sequence(listOfConfig)

  val map = mapSource(
    Map(
      "0_VARIABLE1" -> "1",
      "0_VARIABLE2" -> "2",
      "1_VARIABLE1" -> "3",
      "1_VARIABLE2" -> "4",
      "2_VARIABLE1" -> "5",
      "2_VARIABLE2" -> "6"
      "3_VARIABLE1" -> "7",
    )
  )


val result = read(configOfList).run.provide(map)
// Result: List(Variables(7,None), Variables(5,Some(6)), Variables(3,Some(4)), Variables(1,Some(2)))

val written = write(configOfList).run.provide(result._2)

// Result:
 Map(
  0_VARIABLE1 -> 1,
  0_VARIABLE2 -> 2, 
  1_VARIABLE1 -> 3, 
  1_VARIABLE2 -> 4,
  2_VARIABLE1 -> 5, 
  2_VARIABLE2 -> 6, 
  3_VARIABLE1 -> 7
)
@afsalthaj afsalthaj changed the title Implement list through being able to sequence for user. Make Sequence traversable by implementing Sequence. Sep 30, 2019
@afsalthaj afsalthaj self-assigned this Sep 30, 2019
@afsalthaj
Copy link
Collaborator Author

afsalthaj commented Sep 30, 2019

@wi101 @jdegoes Requesting your comments on this :)

@afsalthaj afsalthaj changed the title Make Sequence traversable by implementing Sequence. Implement xmap2Either and Sequence for Config Sep 30, 2019
@afsalthaj
Copy link
Collaborator Author

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

2 participants