Skip to content

Instantly share code, notes, and snippets.

@daxfohl
Last active February 27, 2017 16:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save daxfohl/a785d1ff72b921d7e90b70f625191a1c to your computer and use it in GitHub Desktop.
Save daxfohl/a785d1ff72b921d7e90b70f625191a1c to your computer and use it in GitHub Desktop.
{-# LANGUAGE MultiParamTypeClasses #-}
module DataLib where
class Record a where
getId :: a -> Int
insert :: Record a => a -> [a] -> [a]
insert r rs = r : rs
update :: Record a => a -> [a] -> [a]
update r rs = map (\r' -> if getId r == getId r' then r else r') rs
delete :: Record a => Int -> [a] -> [a]
delete i rs = filter (\r' -> getId r' /= i) rs
data Person = Person { personId :: Int, name :: String }
instance Record Person where
getId = personId
data Book = Book { bookId :: Int, title :: String }
instance Record Book where
getId = bookId
data Database = Database { employees :: [Person], books :: [Book], customers :: [Person] }
class (Record r) => Table r t where
getRecords :: t -> Database -> [r]
setRecords :: t -> [r] -> Database -> Database
insertRecord :: (Table r t) => t -> r -> Database -> Database
insertRecord t r db =
let records = getRecords t db
newRecords = insert r records
in setRecords t newRecords db
updateRecord :: (Table r t) => t -> r -> Database -> Database
updateRecord t r db =
let records = getRecords t db
newRecords = update r records
in setRecords t newRecords db
deleteRecord :: (Table r t) => t -> Int -> Database -> Database
deleteRecord t i db =
let records = getRecords t db
newRecords = delete i records
in setRecords t newRecords db
data ET = EmployeeTable
instance (Table Person) ET where
getRecords t db = employees db
setRecords t records db = Database records (books db) (customers db)
data BT = BookTable
instance (Table Book) BT where
getRecords t db = books db
setRecords t records db = Database (employees db) records (customers db)
data CT = CustomerTable
instance (Table Person) CT where
getRecords t db = customers db
setRecords t records db = Database (employees db) (books db) records
db = Database [] [] []
bookTable = BookTable
book = Book { bookId = 0, title = "" }
db1 = insertRecord bookTable book db
using System.Linq;
namespace DataLib {
interface IRecord { int Id { get; } }
static class RecordExt {
static public TRecord[] Insert<TRecord>(this TRecord[] rs, TRecord r) where TRecord : IRecord {
return rs.Concat(new[] { r }).ToArray();
}
static public TRecord[] Update<TRecord>(this TRecord[] rs, TRecord r) where TRecord : IRecord {
return rs.Select(r1 => r1.Id == r.Id ? r : r1).ToArray();
}
static public TRecord[] Delete<TRecord>(this TRecord[] rs, int i) where TRecord : IRecord {
return rs.Where(r => r.Id != i).ToArray();
}
}
// We make fields public/mutable for brevity, but use is immutably everywhere.
class Person : IRecord {
public int Id { get; set; }
public string Name { get; set; }
}
class Book : IRecord {
public int Id { get; set; }
public string Title { get; set; }
}
class Database {
public Person[] Employees;
public Book[] Books;
public Person[] Customers;
}
interface ITable<TRecord> where TRecord : IRecord {
TRecord[] GetRecords(Database db);
Database SetRecords(TRecord[] records, Database db);
}
static class TableExt {
static public Database InsertRecord<TRecord>(this ITable<TRecord> t, TRecord r, Database db) where TRecord : IRecord {
var records = t.GetRecords(db);
var newRecords = records.Insert(r);
return t.SetRecords(newRecords, db);
}
static public Database UpdateRecord<TRecord>(this ITable<TRecord> t, TRecord r, Database db) where TRecord : IRecord {
var records = t.GetRecords(db);
var newRecords = records.Update(r);
return t.SetRecords(newRecords, db);
}
static public Database DeleteRecord<TRecord>(this ITable<TRecord> t, int i, Database db) where TRecord : IRecord {
var records = t.GetRecords(db);
var newRecords = records.Delete(i);
return t.SetRecords(newRecords, db);
}
}
class EmployeeTable : ITable<Person> {
public Person[] GetRecords(Database db) {
return db.Employees;
}
public Database SetRecords(Person[] records, Database db) {
return new Database { Employees = records, Books = db.Books, Customers = db.Customers };
}
}
class BookTable : ITable<Book> {
public Book[] GetRecords(Database db) {
return db.Books;
}
public Database SetRecords(Book[] records, Database db) {
return new Database { Employees = db.Employees, Books = records, Customers = db.Customers };
}
}
class CustomerTable : ITable<Person> {
public Person[] GetRecords(Database db) {
return db.Customers;
}
public Database SetRecords(Person[] records, Database db) {
return new Database { Employees = db.Employees, Books = db.Books, Customers = records };
}
}
static class Program {
static void Main() {
var db = new Database { Employees = new Person[0], Books = new Book[0], Customers = new Person[0] };
var bookTable = new BookTable();
var book = new Book { Id = 0, Title = "" };
db = bookTable.InsertRecord(book, db);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment