Skip to content

Instantly share code, notes, and snippets.

@louthy
Created March 27, 2020 14:41
Show Gist options
  • Save louthy/6bbe073089b426d9b8c874ee9b37b6ff to your computer and use it in GitHub Desktop.
Save louthy/6bbe073089b426d9b8c874ee9b37b6ff to your computer and use it in GitHub Desktop.
using System;
using LanguageExt;
using static LanguageExt.Prelude;
namespace StackOverflow1
{
class Program
{
static void Main(string[] args)
{
var s1 = Student.New("Joe Bloggs", 24);
var s2 = Student.New("John Doe", 22);
var s3 = Student.New("Jane Doe", 21);
var t1 = Teacher.New("Richard Smith", 56);
var t2 = Teacher.New("Paul Louth", 44);
Database.AddStudent(s1);
Database.AddStudent(s2);
Database.AddStudent(s3);
Database.AddTeacher(t1);
Database.AddTeacher(t2);
Database.AssignStudentToTeacher(s1, t1);
Database.AssignStudentToTeacher(s2, t1);
Database.AssignStudentToTeacher(s3, t2);
Database.FindStudentTeachers(s1).Iter(Console.WriteLine);
Database.FindStudentTeachers(s2).Iter(Console.WriteLine);
Database.FindStudentTeachers(s3).Iter(Console.WriteLine);
Database.FindTeacherStudents(t1).Iter(Console.WriteLine);
Database.FindTeacherStudents(t2).Iter(Console.WriteLine);
Database.RemoveTeacher(t2);
Database.FindGhostStudents().Iter(Console.WriteLine);
Database.RemoveStudent(s1);
Database.FindTeacherStudents(t1).Iter(Console.WriteLine);
Database.RemoveStudent(s2);
Database.FindTeacherStudents(t1).Iter(Console.WriteLine);
}
}
[Record]
public partial class Student
{
public readonly string Name;
public readonly int Age;
}
[Record]
public partial class Teacher
{
public readonly string Name;
public readonly int Age;
}
public static class Database
{
public static readonly Ref<Map<Teacher, Set<Student>>> TeacherStudents;
public static readonly Ref<Map<Student, Set<Teacher>>> StudentTeachers;
public static readonly Ref<Set<Student>> Students;
public static readonly Ref<Set<Teacher>> Teachers;
static Database()
{
TeacherStudents = Ref(Map<Teacher, Set<Student>>());
StudentTeachers = Ref(Map<Student, Set<Teacher>>());
Students = Ref(Set<Student>());
Teachers = Ref(Set<Teacher>());
}
public static Unit AddTeacher(Teacher teacher) =>
sync(() =>
{
Teachers.Swap(teachers => teachers.Add(teacher));
TeacherStudents.Swap(teachers => teachers.Add(teacher, Empty)); // no students yet
});
public static Unit AddStudent(Student student) =>
sync(() =>
{
Students.Swap(students => students.Add(student));
StudentTeachers.Swap(students => students.Add(student, Empty)); // no teachers yet
});
public static Unit AssignStudentToTeacher(Student student, Teacher teacher) =>
sync(() =>
{
// Add the teacher to the student
StudentTeachers.Swap(students => students.SetItem(student, Some: ts => ts.AddOrUpdate(teacher)));
// Add the student to the teacher
TeacherStudents.Swap(teachers => teachers.SetItem(teacher, Some: ss => ss.AddOrUpdate(student)));
});
public static Unit UnAssignStudentFromTeacher(Student student, Teacher teacher) =>
sync(() =>
{
// Add the teacher to the student
StudentTeachers.Swap(students => students.SetItem(student, Some: ts => ts.Remove(teacher)));
// Add the student to the teacher
TeacherStudents.Swap(teachers => teachers.SetItem(teacher, Some: ss => ss.Remove(student)));
});
public static Unit RemoveTeacher(Teacher teacher) =>
sync(() => {
Teachers.Swap(teachers => teachers.Remove(teacher));
TeacherStudents.Swap(teachers => teachers.Remove(teacher));
StudentTeachers.Swap(students => students.Map(ts => ts.Remove(teacher)));
});
public static Unit RemoveStudent(Student student) =>
sync(() => {
Students.Swap(students => students.Remove(student));
StudentTeachers.Swap(students => students.Remove(student));
TeacherStudents.Swap(teachers => teachers.Map(ss => ss.Remove(student)));
});
public static Option<Teacher> FindTeacher(string name, int age) =>
Teachers.Value.Find(new Teacher(name, age));
public static Option<Student> FindStudent(string name, int age) =>
Students.Value.Find(new Student(name, age));
public static Set<Student> FindTeacherStudents(Teacher teacher) =>
TeacherStudents.Value
.Find(teacher)
.IfNone(Empty);
public static Set<Teacher> FindStudentTeachers(Student student) =>
StudentTeachers.Value
.Find(student)
.IfNone(Empty);
public static Set<Student> FindGhostStudents() =>
toSet(StudentTeachers.Value.Filter(teachers => teachers.IsEmpty).Keys);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment