Как управлять иерархией состояний в функциональном программировании? - PullRequest
3 голосов
/ 18 мая 2019

Скажем, у меня есть класс Student, который имеет много действий:

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

Здесь вы можете заметить, что на этот класс не влияет какое-либо внешнее состояние.

Но если япоместите этот класс в среду Stateful (например, 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, выставленный классом Environment.Если у меня много действий в Student, я ДОЛЖЕН написать такое же количество прокси-функций в School, что разочаровывает и совсем не весело.

Любые советы?Как управлять такого рода государственной иерархией?

1 Ответ

2 голосов
/ 18 мая 2019

Вдохновленный @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) часть может быть заменена объективом, поэтому вам следует подготовить набор объективов, а не набор прокси-функций различной глубины функций, круто!

...