def getUUID(baseurl: String, service: String): IO[String] =
IO async { cb=>
val client = new featherbed.Client(new URL(baseurl))
val simpleGetRequest = client.get(service).send[Response]()
simpleGetRequest.map(_.contentString).map(Right.apply).map(cb(_)).handle {
case err@ErrorResponse(rep, reason) => cb(Left(err))
}
}
Either response from featherbed transformed into a IO async.
Can be executed using:
getUUID("http://httpbin.org/", "uuid").unsafeToFuture
Allow us to change/update a field of the state represented as case class. In our case the case class is:
case class personContact( name: String, phoneNumber: String)
definition how to read/set the field name.
val getterName = ( personcontact: personContact) => personcontact.name
val setterName = ( personcontact: personContact, newName: String) => personcontact.copy( name= newName)
definition of a simple function to modify the name (uppercase)
val nameUpperCase: Eff[ TSP, String] = for {
_ <- modify[TSP, String ]( _.toUpperCase )
result <- get[TSP, String]
}yield result;
val updateName = lensState(nameUpperCase, getterName, setterName)
then we can use it with:
updateName.runState( personContact("lowercasename", "0238")).run
Eff - simple use case implicit lens and functional compose of two functions with different signature.
data:
case class Order(price: Int, currentProfit: Int)
case class UserOrders(orders: List[Order], userName: String)
basic function:
def updateOrdersProfit[E : _writerString : _stateOrder ](currentprice: Int): Eff[ E, Unit] = for {
_ <- modify[E, List[Order]] { orders: List[Order] =>
orders.map { order => order.copy(currentProfit = currentprice - order.price) }
}
} yield ();
def printUserOrders[E: _writerString : _stateUserOrders]:Eff[E,Unit] = for {
v1 <- get[E, UserOrders]
_ <- tell( s"Username: ${v1.userName}, total profit: ${v1.orders.map(_.currentProfit).sum}")
}yield ();
implicit setter/getter from UserOrders to List(Order)
//lens
implicit val getterOrders : UserOrders => List[Order] = (userorders: UserOrders) => userorders.orders
implicit val setterOrders : List[Order] => UserOrders => UserOrders = (orders: List[Order]) => (userorders: UserOrders) => userorders.copy(orders = orders)
the program based on the two functions:
def programUpdateProfitShowResult[E: _writerString : _stateUserOrders](newPrice: Int):Eff[E,Unit] = for {
_ <- updateOrdersProfit(newPrice)
_ <- printUserOrders
}yield();