2014-12-24 11:58:51 +03:00
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
< html xmlns = "http://www.w3.org/1999/xhtml" >
< head >
< meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" / >
< meta http-equiv = "Content-Style-Type" content = "text/css" / >
< meta name = "generator" content = "pandoc" / >
< meta name = "author" content = "2014-12-25" / >
2014-12-24 13:45:21 +03:00
< title > Haskell Relational Record's Query-Building DSL< / title >
2014-12-24 11:58:51 +03:00
< style type = "text/css" > code { white-space : pre ; } < / style >
<!-- configuration parameters -->
< meta name = "defaultView" content = "slideshow" / >
< meta name = "controlVis" content = "hidden" / >
< style type = "text/css" >
table.sourceCode, tr.sourceCode, td.lineNumbers, td.sourceCode {
margin: 0; padding: 0; vertical-align: baseline; border: none; }
table.sourceCode { width: 100%; line-height: 100%; }
td.lineNumbers { text-align: right; padding-right: 4px; padding-left: 4px; color: #aaaaaa; border-right: 1px solid #aaaaaa; }
td.sourceCode { padding-left: 5px; }
code > span.kw { color: #007020; font-weight: bold; }
code > span.dt { color: #902000; }
code > span.dv { color: #40a070; }
code > span.bn { color: #40a070; }
code > span.fl { color: #40a070; }
code > span.ch { color: #4070a0; }
code > span.st { color: #4070a0; }
code > span.co { color: #60a0b0; font-style: italic; }
code > span.ot { color: #007020; }
code > span.al { color: #ff0000; font-weight: bold; }
code > span.fu { color: #06287e; }
code > span.er { color: #ff0000; font-weight: bold; }
< / style >
<!-- style sheet links -->
< link href = "data:text/css,%40import%20url%28data%3Atext%2Fcss%3Bbase64%2CLyogRG8gbm90IGVkaXQgb3Igb3ZlcnJpZGUgdGhlc2Ugc3R5bGVzISBUaGUgc3lzdGVtIHdpbGwgbGlrZWx5IGJyZWFrIGlmIHlvdSBkby4gKi8KCmRpdiNoZWFkZXIsIGRpdiNmb290ZXIsIGRpdiNjb250cm9scywgLnNsaWRlIHtwb3NpdGlvbjogYWJzb2x1dGU7fQpodG1sPmJvZHkgZGl2I2hlYWRlciwgaHRtbD5ib2R5IGRpdiNmb290ZXIsIAogIGh0bWw%2BYm9keSBkaXYjY29udHJvbHMsIGh0bWw%2BYm9keSAuc2xpZGUge3Bvc2l0aW9uOiBmaXhlZDt9Ci5oYW5kb3V0IHtkaXNwbGF5OiBub25lO30KLmxheW91dCB7ZGlzcGxheTogYmxvY2s7fQouc2xpZGUsIC5oaWRlbWUsIC5pbmNyZW1lbnRhbCB7dmlzaWJpbGl0eTogaGlkZGVuO30KI3NsaWRlMCB7dmlzaWJpbGl0eTogdmlzaWJsZTt9Cg%3D%3D%29%3B%20%2F%2A%20required%20to%20make%20the%20slide%20show%20run%20at%20all%20%2A%2F%0A%40import%20url%28data%3Atext%2Fcss%3Bbase64%2CLyogVGhlIGZvbGxvd2luZyBzdHlsZXMgc2l6ZSwgcGxhY2UsIGFuZCBsYXllciB0aGUgc2xpZGUgY29tcG9uZW50cy4KICAgRWRpdCB0aGVzZSBpZiB5b3Ugd2FudCB0byBjaGFuZ2UgdGhlIG92ZXJhbGwgc2xpZGUgbGF5b3V0LgogICBUaGUgY29tbWVudGVkIGxpbmVzIGNhbiBiZSB1bmNvbW1lbnRlZCAoYW5kIG1vZGlmaWVkLCBpZiBuZWNlc3NhcnkpIAogICAgdG8gaGVscCB5b3Ugd2l0aCB0aGUgcmVhcnJhbmdlbWVudCBwcm9jZXNzLiAqLwoKLyogdGFyZ2V0ID0gMTAyNHg3NjggKi8KCmRpdiNoZWFkZXIsIGRpdiNmb290ZXIsIC5zbGlkZSB7d2lkdGg6IDEwMCU7IHRvcDogMDsgbGVmdDogMDt9CmRpdiNoZWFkZXIge3RvcDogMDsgaGVpZ2h0OiAzZW07IHotaW5kZXg6IDE7fQpkaXYjZm9vdGVyIHt0b3A6IGF1dG87IGJvdHRvbTogMDsgaGVpZ2h0OiAyLjVlbTsgei1pbmRleDogNTt9Ci5zbGlkZSB7dG9wOiAwOyB3aWR0aDogOTIlOyBwYWRkaW5nOiAzLjVlbSA0JSA0JTsgei1pbmRleDogMjsgIGxpc3Qtc3R5bGU6IG5vbmU7fQpkaXYjY29udHJvbHMge2xlZnQ6IDUwJTsgYm90dG9tOiAwOyB3aWR0aDogNTAlOyB6LWluZGV4OiAxMDA7fQpkaXYjY29udHJvbHMgZm9ybSB7cG9zaXRpb246IGFic29sdXRlOyBib3R0b206IDA7IHJpZ2h0OiAwOyB3aWR0aDogMTAwJTsKICBtYXJnaW46IDA7fQojY3VycmVudFNsaWRlIHtwb3NpdGlvbjogYWJzb2x1dGU7IHdpZHRoOiAxMCU7IGxlZnQ6IDQ1JTsgYm90dG9tOiAxZW07IHotaW5kZXg6IDEwO30KaHRtbD5ib2R5ICNjdXJyZW50U2xpZGUge3Bvc2l0aW9uOiBmaXhlZDt9CgovKgpkaXYjaGVhZGVyIHtiYWNrZ3JvdW5kOiAjRkNDO30KZGl2I2Zvb3RlciB7YmFja2dyb3VuZDogI0NDRjt9CmRpdiNjb250cm9scyB7YmFja2dyb3VuZDogI0JCRDt9CmRpdiNjdXJyZW50U2xpZGUge2JhY2tncm91bmQ6ICNGRkM7fQoqLwo%3D%29%3B%20%2F%2A%20sets%20basic%20placement%20and%20size%20of%20slide%20components%20%2A%2F%0A%40import%20url%28data%3Atext%2Fcss%3Bbase64%2CLyogRm9sbG93aW5nIGFyZSB0aGUgcHJlc2VudGF0aW9uIHN0eWxlcyAtLSBlZGl0IGF3YXkhICovCgpib2R5IHtiYWNrZ3JvdW5kOiAjRkZGIHVybChkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGg1Z0JPQWNUL0FNREF3TFcxdGIyOXZjYkd4czdPenRiVzF0N2UzdWZuNSsvdjcvZjM5K2Z2NysvMzkvZi8vOGJPenM3VzF0YmUzdDduNTdXOXZiM0d4dWYzOTg3ZTN0Ym41OTd2NzhiVzFyM096czduNXdBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUNINUJBRUFBQUFBTEFBQUFBRG1BRTRCQUFYLzRDRWV6M1VaMVBOQWpwcENwQUxNOUd4TmdMWFVmRDhwQzZCQzFtTW9MQXBHYjduVU1SYVdCTE9td0FHT1JFVmxxSzM4TE5Od2JRSVdtMmZIMmFMU2NKemY4TnFJMUxnOENxcTZ3OUVvT0F3UFpUMEtGQmtJY1Zoa1N3bFFoM0U4RURock9tRUxGRVE1VlRNSlJ3d1FEVHRYRlJsYmoyaFJXd2taaFpoTURCVklOUXNaTXJNVWdxYTVQSE1pRHcwcWRnOGlnSUFPVWp4clZvOVlFRTBWRmFHNnNaNUltajJ6dUZ4RkZCUTFTbW01VUFBVHplSmhua0VWMStxV0Y4MjY4RE84SkE4R2JjSWpEMy92c3JRSXVHZWdLRmt5Sko0TkloQW9VVUxHYjhhRVp3UWxERVIyYTBvMFdkRGVMWUNRQUNDTkl3c2ZscUt4WnB5RUN4NE4vNzdocFc5ZVBnY2lya0V3RjJjakUzRHhmaHhVQjQzSEs0OGJkUnlqUWVGQ0QxVzNLalNrVVczSnhsY0FTdFpnRkFUTFVBQ01NdkJRRlZWQ0NwV201clIwMlF2bWdhM3FkRW50MTBwdDJpR2NnUEJRT2hIanoyZ1ZLQXg4bGlFREJIVUowbTVGb2d4WjJzQUFHQ1JRVE1wQ0xDYXErQVZlL0FsRFc3Qmk1aGd3UzNaelRCcFE0YTNkSk5nZ2dncWN5aGp4aHJydTFKbU1MQ0I0Q01yQ3N5aUxFV010RGZxeUt3cWpacllDcVNDaFQxSTBXa1BJSU1FMzVpVWpERndnT3dMQzlMUEpYVDlheXlCRHluQzN0VGJoYU9ZWnJJU0VMRGhZc0VBMzFrSzhWZkpHd2kzRDFSb1Y5a3JoMWtENzh4N0RjRWFkWjloNWNsODRZRUNFV2Y5b052VVF5WUZpZEhQRkJTV2g5cDhZRjdFSElWRWNXbEFJQVJlR0lZSjExRlYzM1NiaUdjVEFBd0JJaUptRURMaFl3MEppRE1SSWR4L3BZR0dJVXl4bFJvcVVmTkpBZkR3Q0lNSjFKUjVnandneWhLYVNWazZxZUJoQTJwZ1IyQk5LVlNXREJSRE1WQ1FjeGsyUjMxNDcwTktBanp3ZWdHU1NKT3doWG9vR3Zma2lEWEFHOFJnVHlDR24xSHZvVlhQUmwySk04R2NQRDlnM2czQVdNTGZoZndjMHdLWlloYzRnSXp4NVNRcFdpazRHeFFSZmFjR0pwU0RPQVNwZktOMG9JRUVHRFlocTVKcVBIaUFobk5Jc05nT3N1WlFtSVNPbGNXbmJNN0pxRnhpUlBRQ3JLaHc5RldRbWk0Q2UwT29jNG5Wa2tJeTBtaUtqT3Erdzh3UC9GK3kxTjBXVU5RNzc3S3dBL0RNQktJQWFzR3cranJRWUQ0M3F4bE9hVnBPeHAydW9jMFhyclVINU5ZRkRRWVJrSUFDZzU0NlFLcDN4d0Nyc0d4blV4ZXN6YUlaaDc3M3VBcERmampROElFVWEzam53SFZnQkh6bVJlOUx5a0RBODVNMTFzSmlMUWt6cFpQbVNpWVlDQ0J
< link href = "data:text/css,%2F%2A%20don%27t%20change%20this%20unless%20you%20want%20the%20layout%20stuff%20to%20show%20up%20in%20the%20outline%20view%21%20%2A%2F%0A%0A%2Elayout%20div%2C%20%23footer%20%2A%2C%20%23controlForm%20%2A%20%7Bdisplay%3A%20none%3B%7D%0A%23footer%2C%20%23controls%2C%20%23controlForm%2C%20%23navLinks%2C%20%23toggle%20%7B%0A%20%20display%3A%20block%3B%20visibility%3A%20visible%3B%20margin%3A%200%3B%20padding%3A%200%3B%7D%0A%23toggle%20%7Bfloat%3A%20right%3B%20padding%3A%200%2E5em%3B%7D%0Ahtml%3Ebody%20%23toggle%20%7Bposition%3A%20fixed%3B%20top%3A%200%3B%20right%3A%200%3B%7D%0A%0A%2F%2A%20making%20the%20outline%20look%20pretty%2Dish%20%2A%2F%0A%0A%23slide0%20h1%2C%20%23slide0%20h2%2C%20%23slide0%20h3%2C%20%23slide0%20h4%20%7Bborder%3A%20none%3B%20margin%3A%200%3B%7D%0A%23slide0%20h1%20%7Bpadding%2Dtop%3A%201%2E5em%3B%7D%0A%2Eslide%20h1%20%7Bmargin%3A%201%2E5em%200%200%3B%20padding%2Dtop%3A%200%2E25em%3B%0A%20%20border%2Dtop%3A%201px%20solid%20%23888%3B%20border%2Dbottom%3A%201px%20solid%20%23AAA%3B%7D%0A%23toggle%20%7Bborder%3A%201px%20solid%3B%20border%2Dwidth%3A%200%200%201px%201px%3B%20background%3A%20%23FFF%3B%7D%0A" rel = "stylesheet" type = "text/css" media = "screen" id = "outlineStyle" / >
< link href = "data:text/css,%2F%2A%20The%20following%20rule%20is%20necessary%20to%20have%20all%20slides%20appear%20in%20print%21%20DO%20NOT%20REMOVE%20IT%21%20%2A%2F%2Eslide%2C%20ul%20%7Bpage%2Dbreak%2Dinside%3A%20avoid%3B%20visibility%3A%20visible%20%21important%3B%7Dh1%20%7Bpage%2Dbreak%2Dafter%3A%20avoid%3B%7Dbody%20%7Bfont%2Dsize%3A%2012pt%3B%20background%3A%20white%3B%7D%2A%20%7Bcolor%3A%20black%3B%7D%23slide0%20h1%20%7Bfont%2Dsize%3A%20200%25%3B%20border%3A%20none%3B%20margin%3A%200%2E5em%200%200%2E25em%3B%7D%23slide0%20h3%20%7Bmargin%3A%200%3B%20padding%3A%200%3B%7D%23slide0%20h4%20%7Bmargin%3A%200%200%200%2E5em%3B%20padding%3A%200%3B%7D%23slide0%20%7Bmargin%2Dbottom%3A%203em%3B%7Dh1%20%7Bborder%2Dtop%3A%202pt%20solid%20gray%3B%20border%2Dbottom%3A%201px%20dotted%20silver%3B%7D%2Eextra%20%7Bbackground%3A%20transparent%20%21important%3B%7Ddiv%2Eextra%2C%20pre%2Eextra%2C%20%2Eexample%20%7Bfont%2Dsize%3A%2010pt%3B%20color%3A%20%23333%3B%7Dul%2Eextra%20a%20%7Bfont%2Dweight%3A%20bold%3B%7Dp%2Eexample%20%7Bdisplay%3A%20none%3B%7D%23header%20%7Bdisplay%3A%20none%3B%7D%23footer%20h1%20%7Bmargin%3A%200%3B%20border%2Dbottom%3A%201px%20solid%3B%20color%3A%20gray%3B%20font%2Dstyle%3A%20italic%3B%7D%23footer%20h2%2C%20%23controls%20%7Bdisplay%3A%20none%3B%7D%2F%2A%20The%20following%20rule%20keeps%20the%20layout%20stuff%20out%20of%20print%2E%20%20Remove%20at%20your%20own%20risk%21%20%2A%2F%2Elayout%2C%20%2Elayout%20%2A%20%7Bdisplay%3A%20none%20%21important%3B%7D" rel = "stylesheet" type = "text/css" media = "print" id = "slidePrint" / >
< link href = "data:text/css,%2F%2A%20DO%20NOT%20CHANGE%20THESE%20unless%20you%20really%20want%20to%20break%20Opera%20Show%20%2A%2F%0A%2Eslide%20%7B%0A%09visibility%3A%20visible%20%21important%3B%0A%09position%3A%20static%20%21important%3B%0A%09page%2Dbreak%2Dbefore%3A%20always%3B%0A%7D%0A%23slide0%20%7Bpage%2Dbreak%2Dbefore%3A%20avoid%3B%7D%0A" rel = "stylesheet" type = "text/css" media = "projection" id = "operaFix" / >
<!-- S5 JS -->
< script src = "data:application/x-javascript,%2F%2F%20S5%20v1%2E1%20slides%2Ejs%20%2D%2D%20released%20into%20the%20Public%20Domain%0A%2F%2F%0A%2F%2F%20Please%20see%20http%3A%2F%2Fwww%2Emeyerweb%2Ecom%2Feric%2Ftools%2Fs5%2Fcredits%2Ehtml%20for%20information%20%0A%2F%2F%20about%20all%20the%20wonderful%20and%20talented%20contributors%20to%20this%20code%21%0A%0Avar%20undef%3B%0Avar%20slideCSS%20%3D%20%27%27%3B%0Avar%20snum%20%3D%200%3B%0Avar%20smax%20%3D%201%3B%0Avar%20incpos%20%3D%200%3B%0Avar%20number%20%3D%20undef%3B%0Avar%20s5mode%20%3D%20true%3B%0Avar%20defaultView%20%3D%20%27slideshow%27%3B%0Avar%20controlVis%20%3D%20%27visible%27%3B%0A%0Avar%20isIE%20%3D%20navigator%2EappName%20%3D%3D%20%27Microsoft%20Internet%20Explorer%27%20%3F%201%20%3A%200%3B%0Avar%20isOp%20%3D%20navigator%2EuserAgent%2EindexOf%28%27Opera%27%29%20%3E%20%2D1%20%3F%201%20%3A%200%3B%0Avar%20isGe%20%3D%20navigator%2EuserAgent%2EindexOf%28%27Gecko%27%29%20%3E%20%2D1%20%26%26%20navigator%2EuserAgent%2EindexOf%28%27Safari%27%29%20%3C%201%20%3F%201%20%3A%200%3B%0A%0Afunction%20hasClass%28object%2C%20className%29%20%7B%0A%09if%20%28%21object%2EclassName%29%20return%20false%3B%0A%09return%20%28object%2EclassName%2Esearch%28%27%28%5E%7C%5C%5Cs%29%27%20%2B%20className%20%2B%20%27%28%5C%5Cs%7C%24%29%27%29%20%21%3D%20%2D1%29%3B%0A%7D%0A%0Afunction%20hasValue%28object%2C%20value%29%20%7B%0A%09if%20%28%21object%29%20return%20false%3B%0A%09return%20%28object%2Esearch%28%27%28%5E%7C%5C%5Cs%29%27%20%2B%20value%20%2B%20%27%28%5C%5Cs%7C%24%29%27%29%20%21%3D%20%2D1%29%3B%0A%7D%0A%0Afunction%20removeClass%28object%2CclassName%29%20%7B%0A%09if%20%28%21object%29%20return%3B%0A%09object%2EclassName%20%3D%20object%2EclassName%2Ereplace%28new%20RegExp%28%27%28%5E%7C%5C%5Cs%29%27%2BclassName%2B%27%28%5C%5Cs%7C%24%29%27%29%2C%20RegExp%2E%241%2BRegExp%2E%242%29%3B%0A%7D%0A%0Afunction%20addClass%28object%2CclassName%29%20%7B%0A%09if%20%28%21object%20%7C%7C%20hasClass%28object%2C%20className%29%29%20return%3B%0A%09if%20%28object%2EclassName%29%20%7B%0A%09%09object%2EclassName%20%2B%3D%20%27%20%27%2BclassName%3B%0A%09%7D%20else%20%7B%0A%09%09object%2EclassName%20%3D%20className%3B%0A%09%7D%0A%7D%0A%0Afunction%20GetElementsWithClassName%28elementName%2CclassName%29%20%7B%0A%09var%20allElements%20%3D%20document%2EgetElementsByTagName%28elementName%29%3B%0A%09var%20elemColl%20%3D%20new%20Array%28%29%3B%0A%09for%20%28var%20i%20%3D%200%3B%20i%3C%20allElements%2Elength%3B%20i%2B%2B%29%20%7B%0A%09%09if%20%28hasClass%28allElements%5Bi%5D%2C%20className%29%29%20%7B%0A%09%09%09elemColl%5BelemColl%2Elength%5D%20%3D%20allElements%5Bi%5D%3B%0A%09%09%7D%0A%09%7D%0A%09return%20elemColl%3B%0A%7D%0A%0Afunction%20isParentOrSelf%28element%2C%20id%29%20%7B%0A%09if%20%28element%20%3D%3D%20null%20%7C%7C%20element%2EnodeName%3D%3D%27BODY%27%29%20return%20false%3B%0A%09else%20if%20%28element%2Eid%20%3D%3D%20id%29%20return%20true%3B%0A%09else%20return%20isParentOrSelf%28element%2EparentNode%2C%20id%29%3B%0A%7D%0A%0Afunction%20nodeValue%28node%29%20%7B%0A%09var%20result%20%3D%20%22%22%3B%0A%09if%20%28node%2EnodeType%20%3D%3D%201%29%20%7B%0A%09%09var%20children%20%3D%20node%2EchildNodes%3B%0A%09%09for%20%28var%20i%20%3D%200%3B%20i%20%3C%20children%2Elength%3B%20%2B%2Bi%29%20%7B%0A%09%09%09result%20%2B%3D%20nodeValue%28children%5Bi%5D%29%3B%0A%09%09%7D%09%09%0A%09%7D%0A%09else%20if%20%28node%2EnodeType%20%3D%3D%203%29%20%7B%0A%09%09result%20%3D%20node%2EnodeValue%3B%0A%09%7D%0A%09return%28result%29%3B%0A%7D%0A%0Afunction%20slideLabel%28%29%20%7B%0A%09var%20slideColl%20%3D%20GetElementsWithClassName%28%27%2A%27%2C%27slide%27%29%3B%0A%09var%20list%20%3D%20document%2EgetElementById%28%27jumplist%27%29%3B%0A%09smax%20%3D%20slideColl%2Elength%3B%0A%09for%20%28var%20n%20%3D%200%3B%20n%20%3C%20smax%3B%20n%2B%2B%29%20%7B%0A%09%09var%20obj%20%3D%20slideColl%5Bn%5D%3B%0A%0A%09%09var%20did%20%3D%20%27slide%27%20%2B%20n%2EtoString%28%29%3B%0A%09%09obj%2EsetAttribute%28%27id%27%2Cdid%29%3B%0A%09%09if%20%28isOp%29%20continue%3B%0A%0A%09%09var%20otext%20%3D%20%27%27%3B%0A%09%09var%20menu%20%3D%20obj%2EfirstChild%3B%0A%09%
< script src = "data:application/x-javascript,%2F%2A%0ALaTeXMathML%2Ejs%0A%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%0A%0AThis%20file%2C%20in%20this%20form%2C%20is%20due%20to%20Douglas%20Woodall%2C%20June%202006%2E%0AIt%20contains%20JavaScript%20functions%20to%20convert%20%28most%20simple%29%20LaTeX%0Amath%20notation%20to%20Presentation%20MathML%2E%20%20It%20was%20obtained%20by%0Adownloading%20the%20file%20ASCIIMathML%2Ejs%20from%0A%09http%3A%2F%2Fwww1%2Echapman%2Eedu%2F%7Ejipsen%2Fmathml%2Fasciimathdownload%2F%0Aand%20modifying%20it%20so%20that%20it%20carries%20out%20ONLY%20those%20conversions%0Athat%20would%20be%20carried%20out%20in%20LaTeX%2E%20%20A%20description%20of%20the%20original%0Afile%2C%20with%20examples%2C%20can%20be%20found%20at%0A%09www1%2Echapman%2Eedu%2F%7Ejipsen%2Fmathml%2Fasciimath%2Ehtml%0A%09ASCIIMathML%3A%20Math%20on%20the%20web%20for%20everyone%0A%0AHere%20is%20the%20header%20notice%20from%20the%20original%20file%3A%0A%0AASCIIMathML%2Ejs%0A%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%0AThis%20file%20contains%20JavaScript%20functions%20to%20convert%20ASCII%20math%20notation%0Ato%20Presentation%20MathML%2E%20The%20conversion%20is%20done%20while%20the%20%28X%29HTML%20page%0Aloads%2C%20and%20should%20work%20with%20Firefox%2FMozilla%2FNetscape%207%2B%20and%20Internet%0AExplorer%206%2BMathPlayer%20%28http%3A%2F%2Fwww%2Edessci%2Ecom%2Fen%2Fproducts%2Fmathplayer%2F%29%2E%0AJust%20add%20the%20next%20line%20to%20your%20%28X%29HTML%20page%20with%20this%20file%20in%20the%20same%20folder%3A%0A%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22ASCIIMathML%2Ejs%22%3E%3C%2Fscript%3E%0AThis%20is%20a%20convenient%20and%20inexpensive%20solution%20for%20authoring%20MathML%2E%0A%0AVersion%201%2E4%2E7%20Dec%2015%2C%202005%2C%20%28c%29%20Peter%20Jipsen%20http%3A%2F%2Fwww%2Echapman%2Eedu%2F%7Ejipsen%0ALatest%20version%20at%20http%3A%2F%2Fwww%2Echapman%2Eedu%2F%7Ejipsen%2Fmathml%2FASCIIMathML%2Ejs%0AFor%20changes%20see%20http%3A%2F%2Fwww%2Echapman%2Eedu%2F%7Ejipsen%2Fmathml%2Fasciimathchanges%2Etxt%0AIf%20you%20use%20it%20on%20a%20webpage%2C%20please%20send%20the%20URL%20to%20jipsen%40chapman%2Eedu%0A%0AThis%20program%20is%20free%20software%3B%20you%20can%20redistribute%20it%20and%2For%20modify%0Ait%20under%20the%20terms%20of%20the%20GNU%20General%20Public%20License%20as%20published%20by%0Athe%20Free%20Software%20Foundation%3B%20either%20version%202%20of%20the%20License%2C%20or%20%28at%0Ayour%20option%29%20any%20later%20version%2E%0A%0AThis%20program%20is%20distributed%20in%20the%20hope%20that%20it%20will%20be%20useful%2C%0Abut%20WITHOUT%20ANY%20WARRANTY%3B%20without%20even%20the%20implied%20warranty%20of%0AMERCHANTABILITY%20or%20FITNESS%20FOR%20A%20PARTICULAR%20PURPOSE%2E%20See%20the%20GNU%0AGeneral%20Public%20License%20%28at%20http%3A%2F%2Fwww%2Egnu%2Eorg%2Fcopyleft%2Fgpl%2Ehtml%29%0Afor%20more%20details%2E%0A%0ALaTeXMathML%2Ejs%20%28ctd%29%0A%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%3D%0A%0AThe%20instructions%20for%20use%20are%20the%20same%20as%20for%20the%20original%0AASCIIMathML%2Ejs%2C%20except%20that%20of%20course%20the%20line%20you%20add%20to%20your%0Afile%20should%20be%0A%3Cscript%20type%3D%22text%2Fjavascript%22%20src%3D%22LaTeXMathML%2Ejs%22%3E%3C%2Fscript%3E%0AOr%20use%20absolute%20path%20names%20if%20the%20file%20is%20not%20in%20the%20same%20folder%0Aas%20your%20%28X%29HTML%20page%2E%0A%2A%2F%0A%0Avar%20checkForMathML%20%3D%20true%3B%20%20%20%2F%2F%20check%20if%20browser%20can%20display%20MathML%0Avar%20notifyIfNoMathML%20%3D%20true%3B%20%2F%2F%20display%20note%20if%20no%20MathML%20capability%0Avar%20alertIfNoMathML%20%3D%20false%3B%20%20%2F%2F%20show%20alert%20box%20if%20no%20MathML%20capability%0A%2F%2F%20was%20%22red%22%3A%0Avar%20mathcolor%20%3D%20%22%22%3B%09%20%20%20%20%20%2F%2F%20change%20it%20to%20%22%22%20%28to%20inherit%29%20or%20any%20other%20color%0A%2F%2F%20was%20%22serif%22%3A%0Avar%20mathfontfamily%20%3D%20%22%22%3B%20%20%20%20%20%20%2F%2F%20change%20to%20%22%22%20to%20inherit%20%28works%20in%20IE%29%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%2F%2F
< / head >
< body >
< div class = "layout" >
< div id = "controls" > < / div >
< div id = "currentSlide" > < / div >
< div id = "header" > < / div >
< div id = "footer" >
< h1 > Kei Hibino< / h1 >
2014-12-24 13:45:21 +03:00
< h2 > Haskell Relational Record's Query-Building DSL< / h2 >
2014-12-24 11:58:51 +03:00
< / div >
< / div >
< div class = "presentation" >
< div class = "titleslide slide" >
2014-12-24 13:45:21 +03:00
< h1 > Haskell Relational Record's Query-Building DSL< / h1 >
2014-12-24 11:58:51 +03:00
< h2 > 2014-12-25< / h2 >
< h3 > Kei Hibino< / h3 >
< / div >
2014-12-24 13:45:21 +03:00
< div id = "rough-design" class = "titleslide slide section level1" > < h1 > Rough Design< / h1 > < / div > < div id = "query-dsl-basics" class = "slide section level2" >
2014-12-24 11:58:51 +03:00
< h1 > Query DSL Basics< / h1 >
< p > < span class = "LaTeX" > $$\{ (x, y) | x \in X, y \in Y, \pi_1(x) = \pi_2(y) \}$$< / span > < / p >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > [ (x, y) < span class = "fu" > |< / span > x < span class = "ot" > < -< / span > xs, y < span class = "ot" > < -< / span > ys, fst x < span class = "fu" > ==< / span > snd y ] < span class = "co" > -- Comprehension< / span >
2014-12-24 13:45:21 +03:00
< span class = "kw" > do< / span > { x < span class = "ot" > < -< / span > xs; y < span class = "ot" > < -< / span > ys; fst x < span class = "fu" > ==< / span > snd y; return (x, y) } < span class = "co" > -- List Monad< / span > < / code > < / pre >
< p > Building a joined query like list comprehension or list Monad:< / p >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > personAndBirthday ::< / span > < span class = "dt" > Relation< / span > () (< span class = "dt" > Person< / span > , < span class = "dt" > Birthday< / span > )
2014-12-24 11:58:51 +03:00
personAndBirthday < span class = "fu" > =< / span > relation < span class = "fu" > $< / span > < span class = "kw" > do< / span >
p < span class = "ot" > < -< / span > query person < span class = "co" > -- Join product accumulated< / span >
b < span class = "ot" > < -< / span > query birthday
on < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.name' < span class = "fu" > .=.< / span > b < span class = "fu" > !< / span > Birthday.name'
return < span class = "fu" > $< / span > p < span class = "fu" > > < < / span > b< / code > < / pre >
2014-12-25 03:12:12 +03:00
< / div > < div id = "typing" class = "slide section level2" >
< h1 > Typing< / h1 >
2014-12-24 13:45:21 +03:00
< p > A simple and useful method:< / p >
2014-12-24 11:58:51 +03:00
< ul >
2014-12-25 03:12:12 +03:00
< li > Untype and accumulate from typeful DSL terms into a state monad context< / li >
2014-12-24 11:58:51 +03:00
< li > Typeful result< / li >
2014-12-25 03:12:12 +03:00
< li > Phantom context and result type< / li >
2014-12-24 11:58:51 +03:00
< / ul >
2014-12-25 03:12:12 +03:00
< / div > < div id = "state-stack" class = "slide section level2" >
2014-12-24 11:58:51 +03:00
< h1 > State Stack< / h1 >
2014-12-24 13:45:21 +03:00
< p > Haskell Relational Record's query-building DSL accumulates various context in a state monad context stack.< / p >
2014-12-24 11:58:51 +03:00
< ul >
< li > Join product< / li >
< li > Aggregate terms< / li >
< li > Ordering terms< / li >
< li > Restrict predicates< / li >
< / ul >
< / div >
< div id = "contexts-in-state" class = "titleslide slide section level1" > < h1 > Contexts in State< / h1 > < / div > < div id = "join-product" class = "slide section level2" >
2014-12-24 13:45:21 +03:00
< h1 > Join Product< / h1 >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > query ::< / span > < span class = "dt" > MonadQualify< / span > < span class = "dt" > ConfigureQuery< / span > m
< span class = "ot" > => < / span > < span class = "dt" > Relation< / span > () r
< span class = "ot" > -> < / span > m (< span class = "dt" > Projection< / span > < span class = "dt" > Flat< / span > r)
< span class = "co" > -- Used for outer join< / span >
< span class = "ot" > queryMaybe ::< / span > < span class = "dt" > MonadQualify< / span > < span class = "dt" > ConfigureQuery< / span > m
< span class = "ot" > => < / span > < span class = "dt" > Relation< / span > () r
< span class = "ot" > -> < / span > m (< span class = "dt" > Projection< / span > < span class = "dt" > Flat< / span > (< span class = "dt" > Maybe< / span > r))
< span class = "ot" > on ::< / span > < span class = "dt" > MonadQuery< / span > m < span class = "ot" > => < / span > < span class = "dt" > Projection< / span > < span class = "dt" > Flat< / span > (< span class = "dt" > Maybe< / span > < span class = "dt" > Bool< / span > ) < span class = "ot" > -> < / span > m ()< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > 'query' and 'fqueryMaybe' return a Projection type of table form results.< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > .. < span class = "kw" > FROM< / span > ...
< span class = "co" > -- Accumulating uniquely qualified< / span >
< span class = "co" > -- ( like 'as T0', 'as T1' ... )< / span >
< span class = "co" > -- table forms of SQL FROM clause< / span > < / code > < / pre >
< / div > < div id = "join-example" class = "slide section level2" >
< h1 > Join Example< / h1 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > personAndBirthdayL ::< / span > < span class = "dt" > Relation< / span > () (< span class = "dt" > Person< / span > , < span class = "dt" > Maybe< / span > < span class = "dt" > Birthday< / span > )
personAndBirthdayL < span class = "fu" > =< / span > relation < span class = "fu" > $< / span > < span class = "kw" > do< / span >
p < span class = "ot" > < -< / span > query person
b < span class = "ot" > < -< / span > queryMaybe birthday
on < span class = "fu" > $< / span > just (p < span class = "fu" > !< / span > Person.name') < span class = "fu" > .=.< / span > b < span class = "fu" > ?!< / span > Birthday.name'
return < span class = "fu" > $< / span > p < span class = "fu" > > < < / span > b< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > generates left-joined SQL:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span > T0.name < span class = "kw" > AS< / span > f0, T0.age < span class = "kw" > AS< / span > f1, T0.address < span class = "kw" > AS< / span > f2,
T1.name < span class = "kw" > AS< / span > f3, T1.day < span class = "kw" > AS< / span > f4
< span class = "kw" > FROM< / span > PUBLIC.person T0 < span class = "kw" > LEFT< / span > < span class = "kw" > JOIN< / span >
PUBLIC.birthday T1
< span class = "kw" > ON< / span > (T0.name = T1.name)< / code > < / pre >
< / div > < div id = "aggregation" class = "slide section level2" >
< h1 > Aggregation< / h1 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > groupBy ::< / span > < span class = "dt" > MonadAggregate< / span > m
< span class = "ot" > => < / span > < span class = "dt" > Projection< / span > < span class = "dt" > Flat< / span > r
< span class = "co" > -- ^ Projection to add into group by< / span >
< span class = "ot" > -> < / span > m (< span class = "dt" > Projection< / span > < span class = "dt" > Aggregated< / span > r)
< span class = "co" > -- ^ Result context and aggregated projection< / span >
< span class = "ot" > count ::< / span > < span class = "dt" > Projection< / span > < span class = "dt" > Flat< / span > a < span class = "ot" > -> < / span > < span class = "dt" > Projection< / span > < span class = "dt" > Aggregated< / span > < span class = "dt" > Int64< / span >
< span class = "ot" > max' ::< / span > < span class = "dt" > Ord< / span > a
< span class = "ot" > => < / span > < span class = "dt" > Projection< / span > < span class = "dt" > Flat< / span > a < span class = "ot" > -> < / span > < span class = "dt" > Projection< / span > < span class = "dt" > Aggregated< / span > (< span class = "dt" > Maybe< / span > a)< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > 'groupBy' returns a Projection value with an Aggregated context type:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > .. < span class = "kw" > GROUP< / span > < span class = "kw" > BY< / span > ...
< span class = "co" > -- Accumulating keys< / span >
< span class = "co" > -- of SQL GROUP BY clause< / span > < / code > < / pre >
< / div > < div id = "aggregation-example" class = "slide section level2" >
< h1 > Aggregation Example< / h1 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > agesOfFamilies ::< / span > < span class = "dt" > Relation< / span > () (< span class = "dt" > String< / span > , < span class = "dt" > Maybe< / span > < span class = "dt" > Int32< / span > )
agesOfFamilies < span class = "fu" > =< / span > aggregateRelation < span class = "fu" > $< / span > < span class = "kw" > do< / span >
my < span class = "ot" > < -< / span > query myTable
gFam < span class = "ot" > < -< / span > groupBy < span class = "fu" > $< / span > my < span class = "fu" > !< / span > family' < span class = "co" > -- Specify grouping key< / span >
2014-12-25 03:42:21 +03:00
2014-12-24 11:58:51 +03:00
return < span class = "fu" > $< / span > gFam < span class = "fu" > > < < / span > sum' (my < span class = "fu" > !< / span > age') < span class = "co" > -- Aggregated results< / span > < / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > sums ages per family.< / p >
< p > Generated SQL:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span > T0.family < span class = "kw" > AS< / span > f0, < span class = "fu" > SUM< / span > (T0.age) < span class = "kw" > AS< / span > f1
< span class = "kw" > FROM< / span > PUBLIC.my_table T0
< span class = "kw" > GROUP< / span > < span class = "kw" > BY< / span > T0.family< / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "restrict" class = "slide section level2" >
< h1 > Restrict< / h1 >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > restrict ::< / span > < span class = "dt" > MonadRestrict< / span > c m
< span class = "ot" > => < / span > < span class = "dt" > Projection< / span > c (< span class = "dt" > Maybe< / span > < span class = "dt" > Bool< / span > )
< span class = "ot" > -> < / span > m ()
< span class = "ot" > wheres ::< / span > < span class = "dt" > MonadRestrict< / span > < span class = "dt" > Flat< / span > m
< span class = "ot" > => < / span > < span class = "dt" > Projection< / span > < span class = "dt" > Flat< / span > (< span class = "dt" > Maybe< / span > < span class = "dt" > Bool< / span > )
< span class = "ot" > -> < / span > m ()< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > adds a WHERE clause restriction:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > .. < span class = "kw" > WHERE< / span > x < span class = "kw" > AND< / span > y < span class = "kw" > AND< / span > ...
< span class = "co" > -- Accumulating AND predicates< / span >
< span class = "co" > -- of SQL WHERE clause< / span > < / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "restrict-1" class = "slide section level2" >
< h1 > Restrict< / h1 >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > restrict ::< / span > < span class = "dt" > MonadRestrict< / span > c m
< span class = "ot" > => < / span > < span class = "dt" > Projection< / span > c (< span class = "dt" > Maybe< / span > < span class = "dt" > Bool< / span > )
< span class = "ot" > -> < / span > m ()
< span class = "ot" > having ::< / span > < span class = "dt" > MonadRestrict< / span > < span class = "dt" > Aggregated< / span > m
< span class = "ot" > => < / span > < span class = "dt" > Projection< / span > < span class = "dt" > Aggregated< / span > (< span class = "dt" > Maybe< / span > < span class = "dt" > Bool< / span > )
< span class = "ot" > -> < / span > m ()< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > adds a HAVING clause restriction, in which only Projection type values with aggregated context are allowed:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > .. < span class = "kw" > HAVING< / span > x < span class = "kw" > AND< / span > y < span class = "kw" > AND< / span > ...
< span class = "co" > -- Accumulating AND predicates< / span >
< span class = "co" > -- of SQL HAVING clause< / span > < / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "restrict-example" class = "slide section level2" >
< h1 > Restrict Example< / h1 >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > sameBirthdayHeisei' ::< / span > < span class = "dt" > Relation< / span > () (< span class = "dt" > Day< / span > , < span class = "dt" > Int64< / span > )
sameBirthdayHeisei' < span class = "fu" > =< / span > aggregateRelation < span class = "fu" > $< / span > < span class = "kw" > do< / span >
p < span class = "ot" > < -< / span > query person
b < span class = "ot" > < -< / span > query birthday
on < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.name' < span class = "fu" > .=.< / span > b < span class = "fu" > !< / span > Birthday.name'
wheres < span class = "fu" > $< / span > b < span class = "fu" > !< / span > Birthday.day' < span class = "fu" > .> =.< / span > value (fromGregorian < span class = "dv" > 1989< / span > < span class = "dv" > 1< / span > < span class = "dv" > 8< / span > )
gbd < span class = "ot" > < -< / span > groupBy < span class = "fu" > $< / span > b < span class = "fu" > !< / span > Birthday.day'
having < span class = "fu" > $< / span > count (p < span class = "fu" > !< / span > Person.name') < span class = "fu" > .> .< / span > value < span class = "dv" > 1< / span >
return < span class = "fu" > $< / span > gbd < span class = "fu" > > < < / span > count (p < span class = "fu" > !< / span > Person.name')< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > counts people with the same birthday, who were born in the Heisei period.< / p >
< p > Generated SQL:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span > T1.day < span class = "kw" > AS< / span > f0, < span class = "fu" > COUNT< / span > (T0.name) < span class = "kw" > AS< / span > f1
< span class = "kw" > FROM< / span > PUBLIC.person T0 < span class = "kw" > INNER< / span > < span class = "kw" > JOIN< / span > PUBLIC.birthday T1
< span class = "kw" > ON< / span > (T0.name = T1.name)
< span class = "kw" > WHERE< / span > (T1.day > = < span class = "dt" > DATE< / span > < span class = "st" > '1989-01-08'< / span > )
< span class = "kw" > GROUP< / span > < span class = "kw" > BY< / span > T1.day < span class = "kw" > HAVING< / span > (< span class = "fu" > COUNT< / span > (T0.name) > < span class = "dv" > 1< / span > )< / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "restrict-example-1" class = "slide section level2" >
< h1 > Restrict Example< / h1 >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > sameBirthdayHeisei ::< / span > < span class = "dt" > Relation< / span > () (< span class = "dt" > Day< / span > , < span class = "dt" > Int64< / span > )
sameBirthdayHeisei < span class = "fu" > =< / span > aggregateRelation < span class = "fu" > $< / span > < span class = "kw" > do< / span >
p < span class = "ot" > < -< / span > query person
b < span class = "ot" > < -< / span > query birthday
on < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.name' < span class = "fu" > .=.< / span > b < span class = "fu" > !< / span > Birthday.name'
< span class = "kw" > let< / span > birthDay < span class = "fu" > =< / span > b < span class = "fu" > !< / span > Birthday.day'
wheres < span class = "fu" > $< / span > birthDay < span class = "fu" > .> =.< / span > value (fromGregorian < span class = "dv" > 1989< / span > < span class = "dv" > 1< / span > < span class = "dv" > 8< / span > )
gbd < span class = "ot" > < -< / span > groupBy birthDay
< span class = "kw" > let< / span > personCount < span class = "fu" > =< / span > count < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.name'
having < span class = "fu" > $< / span > personCount < span class = "fu" > .> .< / span > value < span class = "dv" > 1< / span >
return < span class = "fu" > $< / span > gbd < span class = "fu" > > < < / span > personCount< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > binds using let.< / p >
2014-12-24 11:58:51 +03:00
< / div > < div id = "ordering" class = "slide section level2" >
< h1 > Ordering< / h1 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > orderBy ::< / span > < span class = "dt" > Monad< / span > m
< span class = "ot" > => < / span > < span class = "dt" > Projection< / span > c t
< span class = "co" > -- ^ Ordering terms to add< / span >
< span class = "ot" > -> < / span > < span class = "dt" > Order< / span >
< span class = "co" > -- ^ Order direction -- Asc | Desc< / span >
< span class = "ot" > -> < / span > < span class = "dt" > Orderings< / span > c m ()
< span class = "co" > -- ^ Result context with ordering< / span > < / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > Only Projection type values with specified (Flat, Aggregated, ...) context are allowed.< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > .. < span class = "kw" > ORDER< / span > < span class = "kw" > BY< / span > ...
< span class = "co" > -- Accumulating terms of ORDER BY clause< / span > < / code > < / pre >
< / div > < div id = "ordering-example" class = "slide section level2" >
< h1 > Ordering Example< / h1 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > personAndBirthdayO ::< / span > < span class = "dt" > Relation< / span > () (< span class = "dt" > Person< / span > , < span class = "dt" > Birthday< / span > )
personAndBirthdayO < span class = "fu" > =< / span > relation < span class = "fu" > $< / span > < span class = "kw" > do< / span >
p < span class = "ot" > < -< / span > query person
b < span class = "ot" > < -< / span > query birthday
on < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.name' < span class = "fu" > .=.< / span > b < span class = "fu" > !< / span > Birthday.name'
orderBy (b < span class = "fu" > !< / span > Birthday.day') < span class = "dt" > Asc< / span > < span class = "co" > -- Specify ordering key< / span >
orderBy (p < span class = "fu" > !< / span > Person.name') < span class = "dt" > Asc< / span >
return < span class = "fu" > $< / span > p < span class = "fu" > > < < / span > b< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > orders by birthday and then name:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span > T0.name < span class = "kw" > AS< / span > f0, T0.age < span class = "kw" > AS< / span > f1, T0.address < span class = "kw" > AS< / span > f2,
T1.name < span class = "kw" > AS< / span > f3, T1.day < span class = "kw" > AS< / span > f4
< span class = "kw" > FROM< / span > PUBLIC.person T0 < span class = "kw" > INNER< / span > < span class = "kw" > JOIN< / span > PUBLIC.birthday T1
< span class = "kw" > ON< / span > (T0.name = T1.name)
< span class = "kw" > ORDER< / span > < span class = "kw" > BY< / span > T1.day < span class = "kw" > ASC< / span > , T0.name < span class = "kw" > ASC< / span > < / code > < / pre >
< / div > < div id = "ordering-example-1" class = "slide section level2" >
< h1 > Ordering Example< / h1 >
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > birthdayHeiseiDesc ::< / span > < span class = "dt" > Relation< / span > () (< span class = "dt" > Day< / span > , < span class = "dt" > Int64< / span > )
birthdayHeiseiDesc < span class = "fu" > =< / span > aggregateRelation < span class = "fu" > $< / span > < span class = "kw" > do< / span >
p < span class = "ot" > < -< / span > query person
b < span class = "ot" > < -< / span > query birthday
on < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.name' < span class = "fu" > .=.< / span > b < span class = "fu" > !< / span > Birthday.name'
< span class = "kw" > let< / span > birthDay < span class = "fu" > =< / span > b < span class = "fu" > !< / span > Birthday.day'
wheres < span class = "fu" > $< / span > birthDay < span class = "fu" > .> =.< / span > value (fromGregorian < span class = "dv" > 1989< / span > < span class = "dv" > 1< / span > < span class = "dv" > 8< / span > )
gbd < span class = "ot" > < -< / span > groupBy birthDay
< span class = "kw" > let< / span > personCount < span class = "fu" > =< / span > count < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.name'
orderBy personCount < span class = "dt" > Desc< / span >
return < span class = "fu" > $< / span > gbd < span class = "fu" > > < < / span > personCount< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > orders by the number of people born on the same Heisei period dates:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span > T1.day < span class = "kw" > AS< / span > f0, < span class = "fu" > COUNT< / span > (T0.name) < span class = "kw" > AS< / span > f1
< span class = "kw" > FROM< / span > PUBLIC.person T0 < span class = "kw" > INNER< / span > < span class = "kw" > JOIN< / span > PUBLIC.birthday T1
< span class = "kw" > ON< / span > (T0.name = T1.name)
< span class = "kw" > WHERE< / span > (T1.day > = < span class = "dt" > DATE< / span > < span class = "st" > '1989-01-08'< / span > )
< span class = "kw" > GROUP< / span > < span class = "kw" > BY< / span > T1.day < span class = "kw" > ORDER< / span > < span class = "kw" > BY< / span > < span class = "fu" > COUNT< / span > (T0.name) < span class = "kw" > DESC< / span > < / code > < / pre >
< / div >
2014-12-24 13:45:21 +03:00
< div id = "other-features" class = "titleslide slide section level1" > < h1 > Other Features< / h1 > < / div > < div id = "placeholders" class = "slide section level2" >
< h1 > Placeholders< / h1 >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > specifyPerson ::< / span > < span class = "dt" > Relation< / span > < span class = "dt" > String< / span > (< span class = "dt" > Person< / span > , < span class = "dt" > Birthday< / span > )
specifyPerson < span class = "fu" > =< / span > relation' < span class = "fu" > $< / span > < span class = "kw" > do< / span >
pb < span class = "ot" > < -< / span > query personAndBirthday < span class = "co" > -- Re-use predefined< / span >
2014-12-24 12:14:02 +03:00
(ph, ()) < span class = "ot" > < -< / span > placeholder
(\ph' < span class = "ot" > -> < / span > wheres < span class = "fu" > $< / span > pb < span class = "fu" > !< / span > fst' < span class = "fu" > !< / span > Person.name' < span class = "fu" > .=.< / span > ph')
2014-12-24 11:58:51 +03:00
return (ph, pb)< / code > < / pre >
2014-12-24 13:45:21 +03:00
< p > specifies a person name using a placeholder:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span > T2.f0 < span class = "kw" > AS< / span > f0, T2.f1 < span class = "kw" > AS< / span > f1, T2.f2 < span class = "kw" > AS< / span > f2,
T2.f3 < span class = "kw" > AS< / span > f3, T2.f4 < span class = "kw" > AS< / span > f4
2014-12-24 12:14:02 +03:00
< span class = "kw" > FROM< / span > (< span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span >
T0.name < span class = "kw" > AS< / span > f0, T0.age < span class = "kw" > AS< / span > f1, T0.address < span class = "kw" > AS< / span > f2,
T1.name < span class = "kw" > AS< / span > f3, T1.day < span class = "kw" > AS< / span > f4
2014-12-24 11:58:51 +03:00
< span class = "kw" > FROM< / span > PUBLIC.person T0 < span class = "kw" > INNER< / span > < span class = "kw" > JOIN< / span >
PUBLIC.birthday T1
< span class = "kw" > ON< / span > (T0.name = T1.name)) T2
< span class = "kw" > WHERE< / span > (T2.f0 = ?)< / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "map-sql-values-to-a-haskell-record" class = "slide section level2" >
< h1 > Map SQL Values to a Haskell Record< / h1 >
< p > Mapping to records using Applicative style:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > (|$|) ::< / span > (< span class = "dt" > ProjectableFunctor< / span > p, < span class = "dt" > ProductConstructor< / span > (a < span class = "ot" > -> < / span > b))
< span class = "ot" > => < / span > (a < span class = "ot" > -> < / span > b)
< span class = "ot" > -> < / span > p a
< span class = "ot" > -> < / span > p b
< span class = "ot" > (|*|) ::< / span > < span class = "dt" > ProjectableApplicative< / span > p
< span class = "ot" > => < / span > p (a < span class = "ot" > -> < / span > b)
< span class = "ot" > -> < / span > p a
< span class = "ot" > -> < / span > p b< / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "record-mapping---projections" class = "slide section level2" >
< h1 > Record Mapping - Projections< / h1 >
< p > Assign record types to an SQL projection:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > personAndBirthdayT ::< / span > < span class = "dt" > Relation< / span > () < span class = "dt" > PersonAndBirthday< / span >
personAndBirthdayT < span class = "fu" > =< / span > relation < span class = "fu" > $< / span > < span class = "kw" > do< / span >
p < span class = "ot" > < -< / span > query person
b < span class = "ot" > < -< / span > query birthday
wheres < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.name' < span class = "fu" > .=.< / span > b < span class = "fu" > !< / span > Birthday.name'
2014-12-24 12:14:02 +03:00
< span class = "co" > -- Build record phantom type< / span >
return < span class = "fu" > $< / span > < span class = "dt" > PersonAndBirthday< / span > < span class = "fu" > |$|< / span > p < span class = "fu" > |*|< / span > b
2014-12-24 11:58:51 +03:00
< span class = "ot" > (|$|) ::< / span > < span class = "dt" > ProductConstructor< / span > (a < span class = "ot" > -> < / span > b)
< span class = "ot" > => < / span > (a < span class = "ot" > -> < / span > b) < span class = "ot" > -> < / span > < span class = "dt" > Projection< / span > c a < span class = "ot" > -> < / span > < span class = "dt" > Projection< / span > c b
< span class = "ot" > (|*|) ::< / span > < span class = "dt" > Projection< / span > c (a < span class = "ot" > -> < / span > b) < span class = "ot" > -> < / span > < span class = "dt" > Projection< / span > c a < span class = "ot" > -> < / span > < span class = "dt" > Projection< / span > c b< / code > < / pre >
2014-12-25 04:18:33 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span > T0.name < span class = "kw" > AS< / span > f0, T0.age < span class = "kw" > AS< / span > f1, T0.address < span class = "kw" > AS< / span > f2,
T1.name < span class = "kw" > AS< / span > f3, T1.day < span class = "kw" > AS< / span > f4
< span class = "kw" > FROM< / span > PUBLIC.person T0 < span class = "kw" > INNER< / span > < span class = "kw" > JOIN< / span > PUBLIC.birthday T1
< span class = "kw" > ON< / span > (T0.name = T1.name)< / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "record-mapping---column-selectors" class = "slide section level2" >
< h1 > Record Mapping - Column Selectors< / h1 >
< p > Column selectors can be mapped to a record:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > Birthday.day'< span class = "ot" > ::< / span > < span class = "dt" > Pi< / span > < span class = "dt" > Birthday< / span > < span class = "dt" > Day< / span >
< span class = "ot" > uncurryPB ::< / span > < span class = "dt" > Pi< / span > (< span class = "dt" > Person< / span > , < span class = "dt" > Birthday< / span > ) < span class = "dt" > PersonAndBirthday< / span >
uncurryPB < span class = "fu" > =< / span > < span class = "dt" > PersonAndBirthday< / span > < span class = "fu" > |$|< / span > fst' < span class = "fu" > |*|< / span > snd'
< span class = "ot" > (|$|) ::< / span > < span class = "dt" > ProductConstructor< / span > (a < span class = "ot" > -> < / span > b)
< span class = "ot" > => < / span > (a < span class = "ot" > -> < / span > b) < span class = "ot" > -> < / span > < span class = "dt" > Pi< / span > r a < span class = "ot" > -> < / span > < span class = "dt" > Pi< / span > r b
< span class = "ot" > (|*|) ::< / span > < span class = "dt" > Pi< / span > r (a < span class = "ot" > -> < / span > b) < span class = "ot" > -> < / span > < span class = "dt" > Pi< / span > r a < span class = "ot" > -> < / span > < span class = "dt" > Pi< / span > r b< / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "record-mapping---placeholders" class = "slide section level2" >
< h1 > Record Mapping - Placeholders< / h1 >
< p > Placeholders can be mapped to a record:< / p >
2014-12-25 03:42:21 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > personAndBirthdayP2 ::< / span > < span class = "dt" > Relation< / span > < span class = "dt" > Person< / span > < span class = "dt" > PersonAndBirthday< / span >
2014-12-24 11:58:51 +03:00
personAndBirthdayP2 < span class = "fu" > =< / span > relation' < span class = "fu" > $< / span > < span class = "kw" > do< / span >
p < span class = "ot" > < -< / span > query person
b < span class = "ot" > < -< / span > query birthday
2014-12-25 03:42:21 +03:00
(ph0, ()) < span class = "ot" > < -< / span > placeholder (\ph0' < span class = "ot" > -> < / span > on < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.name' < span class = "fu" > .=.< / span > ph0')
(ph1, ()) < span class = "ot" > < -< / span > placeholder (\ph1' < span class = "ot" > -> < / span > on < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.age' < span class = "fu" > .=.< / span > ph1')
(ph2, ()) < span class = "ot" > < -< / span > placeholder (\ph2' < span class = "ot" > -> < / span > on < span class = "fu" > $< / span > p < span class = "fu" > !< / span > Person.address' < span class = "fu" > .=.< / span > ph2')
return (< span class = "dt" > Person< / span > < span class = "fu" > |$|< / span > ph0 < span class = "fu" > |*|< / span > ph1 < span class = "fu" > |*|< / span > ph2,
< span class = "dt" > PersonAndBirthday< / span > < span class = "fu" > |$|< / span > p < span class = "fu" > |*|< / span > b)
< span class = "ot" > (|$|) ::< / span > < span class = "dt" > ProductConstructor< / span > (a < span class = "ot" > -> < / span > b)
< span class = "ot" > => < / span > (a < span class = "ot" > -> < / span > b) < span class = "ot" > -> < / span > < span class = "dt" > Placeholders< / span > a < span class = "ot" > -> < / span > < span class = "dt" > Placeholders< / span > b
< span class = "ot" > (|*|) ::< / span > < span class = "dt" > Placeholders< / span > (a < span class = "ot" > -> < / span > b) < span class = "ot" > -> < / span > < span class = "dt" > Placeholders< / span > a < span class = "ot" > -> < / span > < span class = "dt" > Placeholders< / span > b< / code > < / pre >
2014-12-25 04:18:33 +03:00
< p > Generated SQL:< / p >
2014-12-25 03:42:21 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span > T0.name < span class = "kw" > AS< / span > f0, T0.age < span class = "kw" > AS< / span > f1, T0.address < span class = "kw" > AS< / span > f2,
T1.name < span class = "kw" > AS< / span > f3, T1.day < span class = "kw" > AS< / span > f4
< span class = "kw" > FROM< / span > PUBLIC.person T0 < span class = "kw" > INNER< / span > < span class = "kw" > JOIN< / span > PUBLIC.birthday T1
< span class = "kw" > ON< / span > (((T0.name = ?) < span class = "kw" > AND< / span > (T0.age = ?)) < span class = "kw" > AND< / span > (T0.address = ?))< / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "record-mapping---record-placeholders" class = "slide section level2" >
< h1 > Record Mapping - Record Placeholders< / h1 >
< p > Record-typed placeholder:< / p >
2014-12-25 03:42:21 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > placeholder ::< / span > (< span class = "dt" > PersistableWidth< / span > t, < span class = "dt" > Monad< / span > m)
< span class = "ot" > => < / span > (< span class = "dt" > Projection< / span > c t < span class = "ot" > -> < / span > m a) < span class = "ot" > -> < / span > m (< span class = "dt" > PlaceHolders< / span > t, a)
< span class = "ot" > personAndBirthdayP ::< / span > < span class = "dt" > Relation< / span > < span class = "dt" > Person< / span > < span class = "dt" > PersonAndBirthday< / span >
2014-12-24 11:58:51 +03:00
personAndBirthdayP < span class = "fu" > =< / span > relation' < span class = "fu" > $< / span > < span class = "kw" > do< / span >
p < span class = "ot" > < -< / span > query person
b < span class = "ot" > < -< / span > query birthday
(ph, ()) < span class = "ot" > < -< / span > placeholder (\ph' < span class = "ot" > -> < / span > wheres < span class = "fu" > $< / span > p < span class = "fu" > .=.< / span > ph')
return < span class = "fu" > $< / span > (ph, < span class = "dt" > PersonAndBirthday< / span > < span class = "fu" > |$|< / span > p < span class = "fu" > |*|< / span > b)< / code > < / pre >
2014-12-25 04:18:33 +03:00
< p > row value of Placeholders:< / p >
2014-12-25 03:12:12 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span > T0.name < span class = "kw" > AS< / span > f0, T0.age < span class = "kw" > AS< / span > f1, T0.address < span class = "kw" > AS< / span > f2,
T1.name < span class = "kw" > AS< / span > f3, T1.day < span class = "kw" > AS< / span > f4
< span class = "kw" > FROM< / span > PUBLIC.person T0 < span class = "kw" > INNER< / span > < span class = "kw" > JOIN< / span > PUBLIC.birthday T1
2014-12-25 03:42:21 +03:00
< span class = "kw" > ON< / span > ((T0.name, T0.age, T0.address) = (?, ?, ?))< / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "questions" class = "slide section level2" >
< h1 > Questions?< / h1 >
2014-12-24 11:58:51 +03:00
< / div > < div id = "window-function" class = "slide section level2" >
< h1 > Window Function< / h1 >
2014-12-24 13:45:21 +03:00
< p > Monadic-style window building:< / p >
2014-12-24 11:58:51 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > ageRankOfFamilies ::< / span > < span class = "dt" > Relation< / span > () ((< span class = "dt" > Int64< / span > , < span class = "dt" > String< / span > ), < span class = "dt" > Int32< / span > )
ageRankOfFamilies < span class = "fu" > =< / span > relation < span class = "fu" > $< / span > < span class = "kw" > do< / span >
my < span class = "ot" > < -< / span > query myTable
return < span class = "fu" > $< / span >
rank < span class = "ot" > `over`< / span > < span class = "kw" > do< / span >
partitionBy < span class = "fu" > $< / span > my < span class = "fu" > !< / span > family' < span class = "co" > -- Monad to build window< / span >
orderBy (my < span class = "fu" > !< / span > age') < span class = "dt" > Desc< / span >
< span class = "fu" > > < < / span >
2014-12-25 04:18:33 +03:00
my < span class = "fu" > !< / span > family' < span class = "fu" > > < < / span > my < span class = "fu" > !< / span > age'< / code > < / pre >
2014-12-25 03:12:12 +03:00
< pre class = "sourceCode sql" > < code class = "sourceCode sql" > < span class = "kw" > SELECT< / span > < span class = "kw" > ALL< / span >
< span class = "fu" > RANK< / span > () < span class = "kw" > OVER< / span > (< span class = "kw" > PARTITION< / span > < span class = "kw" > BY< / span > T0.family < span class = "kw" > ORDER< / span > < span class = "kw" > BY< / span > T0.age < span class = "kw" > DESC< / span > ) < span class = "kw" > AS< / span > f0,
T0.family < span class = "kw" > AS< / span > f1, T0.age < span class = "kw" > AS< / span > f2
< span class = "kw" > FROM< / span > PUBLIC.my_table T0< / code > < / pre >
2014-12-24 11:58:51 +03:00
< / div > < div id = "discussion" class = "slide section level2" >
< h1 > Discussion< / h1 >
2014-12-24 12:14:02 +03:00
< / div >
< div id = "others" class = "titleslide slide section level1" > < h1 > Others< / h1 > < / div > < div id = "exists-operator" class = "slide section level2" >
2014-12-24 13:45:21 +03:00
< h1 > exists Operator< / h1 >
2014-12-24 12:14:02 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > exists ::< / span > (< span class = "dt" > SqlProjectable< / span > p, < span class = "dt" > ProjectableShowSql< / span > p)
< span class = "ot" > => < / span > < span class = "dt" > ListProjection< / span > (< span class = "dt" > Projection< / span > < span class = "dt" > Exists< / span > ) r < span class = "ot" > -> < / span > p (< span class = "dt" > Maybe< / span > < span class = "dt" > Bool< / span > )
< span class = "ot" > values ::< / span > (< span class = "dt" > ShowConstantTermsSQL< / span > t, < span class = "dt" > SqlProjectable< / span > p)
< span class = "ot" > => < / span > [t] < span class = "ot" > -> < / span > < span class = "dt" > ListProjection< / span > p t
< span class = "ot" > queryList ::< / span > < span class = "dt" > MonadQualify< / span > < span class = "dt" > ConfigureQuery< / span > m
< span class = "ot" > => < / span > < span class = "dt" > Relation< / span > () r
< span class = "ot" > -> < / span > m (< span class = "dt" > ListProjection< / span > (< span class = "dt" > Projection< / span > c) r)< / code > < / pre >
2014-12-24 11:58:51 +03:00
< / div > < div id = "in-operator" class = "slide section level2" >
2014-12-24 13:45:21 +03:00
< h1 > in' Operator< / h1 >
2014-12-24 12:14:02 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > in' ::< / span > (< span class = "dt" > SqlProjectable< / span > p, < span class = "dt" > ProjectableShowSql< / span > p)
< span class = "ot" > => < / span > p t < span class = "ot" > -> < / span > < span class = "dt" > ListProjection< / span > p t < span class = "ot" > -> < / span > p (< span class = "dt" > Maybe< / span > < span class = "dt" > Bool< / span > )< / code > < / pre >
2014-12-24 13:45:21 +03:00
< / div > < div id = "scalar-queries" class = "slide section level2" >
< h1 > Scalar Queries< / h1 >
2014-12-24 12:14:02 +03:00
< pre class = "sourceCode haskell" > < code class = "sourceCode haskell" > < span class = "ot" > queryScalar ::< / span > (< span class = "dt" > MonadQualify< / span > < span class = "dt" > ConfigureQuery< / span > m, < span class = "dt" > ScalarDegree< / span > r)
< span class = "ot" > => < / span > < span class = "dt" > UniqueRelation< / span > () c r
< span class = "ot" > -> < / span > m (< span class = "dt" > Projection< / span > c (< span class = "dt" > Maybe< / span > r))< / code > < / pre >
2014-12-24 11:58:51 +03:00
< / div >
< / div >
< / body >
< / html >