haskell - Reconciling lens usage with database access -
i've been playing around lenses recently, , finding them pleasant intended usage - digging complex data structures. 1 of areas i'd appreciate them in database access (specifically sqlite, think question generalizes dbs), , yet can't see way write lenses don't heavily sacrifice either performance or granularity.
if write lens (or think prism, in light of nullable fields?) db table, table row, , row column, each step of incurs db access, meaning ought 1 access @ minimum 4.
on other hand, if aim map db access 1:1 uses of lens/prism, big do-everything lenses can't broken smaller pieces when do want see columns in table, , on.
does make sense @ use lenses db, , if missing obvious way avoid having duplicate work avoid unnecessary db access?
it sound me want use lens in way similar linq iqueryable in c#.
eg if have types:
data project = project { _projectid :: int , _projectpriority :: int , _projectname :: string , _projecttasks :: [task] } deriving (show) data task = task { _taskid :: int , _taskname :: string , _taskestimate :: int } deriving (show) makelenses ''project makelenses ''task and database:
create table projects ( id, name, priority); create table tasks (id, name, estimate, projectid); insert projects values (1, 'proj', 1), (2, 'another proj', 2); insert tasks values (1, 'task1', 30, 1), (2, 'another', 40, 1), (3, 'task3', 20, 2), (4, 'more', 80, 2); if wanted list of task names projects priority greater 1, nice if use:
highprioritytasks :: io [string] highprioritytasks = db ^.. projects . filtered (\p -> p ^. projectpriority > 1 ) . projecttasks . traverse . taskname and have query database using query:
select t.name projects p inner join tasks t on t.projectid = p.id p.priority > 1; unfortunately, isn't possible library. basically, efficient database wise, (normally) have everthing in 1 query. wouldn't acceptable this:
select * projects priority > 1; each project: select name tasks projectid = <project>.id unfortunately, isn't possible decompose functions know built them up. apart type, can't find out function without running it. there no way extract data out of filtered function build query. nor possible extract sub lens out of full expression. isn't possible using lens library.
the best can @ moment query database using 1 set of functions, , query resulting data using lens. see blog post yesod example of this.
a related question if possible @ all. so, need create sublanguage numeric , string operators, , composition tracks done. possible. example, can build num type records done it:
data trackednum = trackednum :-: trackednum | trackednum :+: trackednum | trackednum :*: trackednum | abs trackednum | signum trackednum | value integer deriving (show) instance num trackednum + b = :+: b * b = :*: b - b = :-: b abs = abs signum = signum frominteger = value t :: trackednum t = 3 + 4 * 2 - abs (-34) > t (value 3 :+: (value 4 :*: value 2)) :-: abs (value 0 :-: value 34) repeat process boolean operators (you need new type class this), list operators, , function composition (ie category class), , should able make "white-box" function, used create efficient sql query. isn't trivial undertaking though!
Comments
Post a Comment