Skip to content

Instantly share code, notes, and snippets.

@davegurnell
Last active April 16, 2021 12:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davegurnell/50781a6eafd39632f0af7cdb1c7323c0 to your computer and use it in GitHub Desktop.
Save davegurnell/50781a6eafd39632f0af7cdb1c7323c0 to your computer and use it in GitHub Desktop.
package sandbox
import cats.data.Kleisli
import cats.implicits._
case class User(username: String, avatarUrl: String, profileId: Int)
case class Avatar(url: String, monochrome: Boolean)
case class Profile(id: Int, age: Int)
object ComposingStuff extends App {
val users: List[User] = List(
User("dave", "http://dave.jpg", 1)
)
val avatars: List[Avatar] = List(
// Avatar("http://dave.jpg", true)
)
val profiles: List[Profile] = List(
// Profile(1, 42)
)
type Result[A] = Either[List[Throwable], A]
val fetchUser: Kleisli[Result, String, User] =
Kleisli { username =>
println("fetching user " + username)
val answer = users
.find(_.username == username)
.toRight(List(new Exception("user not found")))
println("result of fetching user " + answer)
answer
}
val fetchAvatar: Kleisli[Result, User, Avatar] =
Kleisli { user =>
println("fetching avatar " + user)
val answer = avatars
.find(_.url == user.avatarUrl)
.toRight(List(new Exception("avatar not found")))
println("result of fetching avatar " + answer)
answer
}
val fetchProfile: Kleisli[Result, User, Profile] =
Kleisli { user =>
println("fetching profile " + user)
val answer = profiles
.find(_.id == user.profileId)
.toRight(List(new Exception("profile not found")))
println("result of fetching profile " + answer)
answer
}
val fetchAvatarAndProfile: Kleisli[Result, User, (Avatar, Profile)] =
(fetchAvatar, fetchProfile).parTupled
val fetchAvatarAndProfileByUsername: Kleisli[Result, String, (Avatar, Profile)] =
fetchUser.andThen(fetchAvatarAndProfile)
println(fetchAvatarAndProfileByUsername.run("dave"))
}
// EXERCISE
//
// type RetrievalFunc[A, B] = A => Either[String, B]
//
// case class IceCream(name: String, numCherries: Int, inCone: Boolean)
//
// type OverallInput = List[String]
// type OverallOutput = IceCream
//
// 1. ~Define Retrieval[A, B] as a Kleisli~
// 2. Write instances of Retrieval to:
// - return the first, second, and third params in a list of string
// - convert a string to an int
// - convert a string to an boolean
// 3. Write an instance of Retrieval to:
// - convert a list of strings to a IceCream
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment