Reputation: 754
Say I have a Student
class which has lots of actions:
final case class Student(name: String, knowledge: List[String]) {
def learn(item: String) : Student = this.copy(knowledge = knowledge :+ item)
}
Here you can notice that this class is not influenced by any outer State.
But if I put this class into a Stateful environment(like a School
):
final case class School(students: Map[String, Student]) {
def learn(studentName: String, item: String) : State[School, Student] = State {
oldSchool => {
val oldStudent = students.get(studentName).getOrElse(Student(studentName, List()))
val newStudent = oldStudent.learn(item)
oldSchool.copy(students = students + (studentName -> newStudent)) -> newStudent
}
}
}
And then I cannot use student.learn(info)
directly, for Student
even doesn't know the environment(School
class) exists. So if I want to call the actions of a student, I have to call the proxy function
exposed by the Environment class. If I have lots of actions in Student
, I HAVE TO write the same count of proxy functions in School
, which is frustrating and not fun at all.
Any advices? How to manage this kind of State hierarchy?
Upvotes: 3
Views: 295
Reputation: 754
Inspired by @WillemVanOnsem, here is my solution.
def updateStudent: String => (Student => Student) => School =
name =>
func =>
this.copy(
students = students + (name -> func(
students.get(name).getOrElse(Student(name, List()))
))
)
And the usage likes:
val stu1 = Student("name1", List())
val school = School(Map(stu1.name -> stu1))
val newSchool = school.updateStudent("name1") { student =>
student.learn("someItem")
}
And I notice that if your hierarchy is really deep, the (Student => Student)
part can be replaced by Lens, so the you should prepare a bunch of Lens, rather than a bunch of Proxy Functions of different depth of functions, cool!
Upvotes: 2