Last active
February 27, 2017 16:09
-
-
Save daxfohl/a785d1ff72b921d7e90b70f625191a1c to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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