如何在功能编程中管理国家层次结构



说我有一个Student类,有很多动作:

final case class Student(name: String, knowledge: List[String]) {
  def learn(item: String) : Student = this.copy(knowledge = knowledge :+ item)
}

在这里您可以注意到此类不受任何外部状态的影响。

但是,如果我将此课程放入状态环境中(例如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
    }
  }
}

,然后我无法直接使用student.learn(info),因为Student甚至不知道存在环境(School类(。因此,如果我想调用学生的动作,我必须称呼环境类暴露的proxy function。如果我在Student中有很多操作,则I 必须School中写下相同的代理函数计数,这很令人沮丧,根本不有趣。

有什么建议吗?如何管理这种状态层次结构?

受@willemvanonsem启发,这是我的解决方案。

  def updateStudent: String => (Student => Student) => School =
    name =>
      func =>
        this.copy(
          students = students + (name -> func(
            students.get(name).getOrElse(Student(name, List()))
          ))
        )

和用法喜欢:

    val stu1   = Student("name1", List())
    val school = School(Map(stu1.name -> stu1))
    val newSchool = school.updateStudent("name1") { student =>
      student.learn("someItem")
    }

我注意到,如果您的层次结构确实很深,则可以用镜头代替(Student => Student)零件,因此您应该准备一堆镜头,而不是不同功能深度的代理功能,很酷!

最新更新