haskell-relational-record/doc/slide/tsukuba-201412/DSL.html

395 lines
327 KiB
HTML
Raw Normal View History

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">&lt;-</span> xs, y <span class="ot">&lt;-</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">&lt;-</span> xs; y <span class="ot">&lt;-</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">&lt;-</span> query person <span class="co">-- Join product accumulated</span>
b <span class="ot">&lt;-</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">&gt;&lt;</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">=&gt;</span> <span class="dt">Relation</span> () r
<span class="ot">-&gt;</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">=&gt;</span> <span class="dt">Relation</span> () r
<span class="ot">-&gt;</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">=&gt;</span> <span class="dt">Projection</span> <span class="dt">Flat</span> (<span class="dt">Maybe</span> <span class="dt">Bool</span>) <span class="ot">-&gt;</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">&lt;-</span> query person
b <span class="ot">&lt;-</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">&gt;&lt;</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">=&gt;</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">-&gt;</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">-&gt;</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">=&gt;</span> <span class="dt">Projection</span> <span class="dt">Flat</span> a <span class="ot">-&gt;</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">&lt;-</span> query myTable
gFam <span class="ot">&lt;-</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">&gt;&lt;</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">=&gt;</span> <span class="dt">Projection</span> c (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">-&gt;</span> m ()
<span class="ot">wheres ::</span> <span class="dt">MonadRestrict</span> <span class="dt">Flat</span> m
<span class="ot">=&gt;</span> <span class="dt">Projection</span> <span class="dt">Flat</span> (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">-&gt;</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">=&gt;</span> <span class="dt">Projection</span> c (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">-&gt;</span> m ()
<span class="ot">having ::</span> <span class="dt">MonadRestrict</span> <span class="dt">Aggregated</span> m
<span class="ot">=&gt;</span> <span class="dt">Projection</span> <span class="dt">Aggregated</span> (<span class="dt">Maybe</span> <span class="dt">Bool</span>)
<span class="ot">-&gt;</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">&lt;-</span> query person
b <span class="ot">&lt;-</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">.&gt;=.</span> value (fromGregorian <span class="dv">1989</span> <span class="dv">1</span> <span class="dv">8</span>)
gbd <span class="ot">&lt;-</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">.&gt;.</span> value <span class="dv">1</span>
return <span class="fu">$</span> gbd <span class="fu">&gt;&lt;</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 &gt;= <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) &gt; <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">&lt;-</span> query person
b <span class="ot">&lt;-</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">.&gt;=.</span> value (fromGregorian <span class="dv">1989</span> <span class="dv">1</span> <span class="dv">8</span>)
gbd <span class="ot">&lt;-</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">.&gt;.</span> value <span class="dv">1</span>
return <span class="fu">$</span> gbd <span class="fu">&gt;&lt;</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">=&gt;</span> <span class="dt">Projection</span> c t
<span class="co">-- ^ Ordering terms to add</span>
<span class="ot">-&gt;</span> <span class="dt">Order</span>
<span class="co">-- ^ Order direction -- Asc | Desc</span>
<span class="ot">-&gt;</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">&lt;-</span> query person
b <span class="ot">&lt;-</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">&gt;&lt;</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">&lt;-</span> query person
b <span class="ot">&lt;-</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">.&gt;=.</span> value (fromGregorian <span class="dv">1989</span> <span class="dv">1</span> <span class="dv">8</span>)
gbd <span class="ot">&lt;-</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">&gt;&lt;</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 &gt;= <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">&lt;-</span> query personAndBirthday <span class="co">-- Re-use predefined</span>
2014-12-24 12:14:02 +03:00
(ph, ()) <span class="ot">&lt;-</span> placeholder
(\ph' <span class="ot">-&gt;</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">-&gt;</span> b))
<span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b)
<span class="ot">-&gt;</span> p a
<span class="ot">-&gt;</span> p b
<span class="ot">(|*|) ::</span> <span class="dt">ProjectableApplicative</span> p
<span class="ot">=&gt;</span> p (a <span class="ot">-&gt;</span> b)
<span class="ot">-&gt;</span> p a
<span class="ot">-&gt;</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">&lt;-</span> query person
b <span class="ot">&lt;-</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">-&gt;</span> b)
<span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Projection</span> c a <span class="ot">-&gt;</span> <span class="dt">Projection</span> c b
<span class="ot">(|*|) ::</span> <span class="dt">Projection</span> c (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Projection</span> c a <span class="ot">-&gt;</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">-&gt;</span> b)
<span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Pi</span> r a <span class="ot">-&gt;</span> <span class="dt">Pi</span> r b
<span class="ot">(|*|) ::</span> <span class="dt">Pi</span> r (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Pi</span> r a <span class="ot">-&gt;</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">&lt;-</span> query person
b <span class="ot">&lt;-</span> query birthday
2014-12-25 03:42:21 +03:00
(ph0, ()) <span class="ot">&lt;-</span> placeholder (\ph0' <span class="ot">-&gt;</span> on <span class="fu">$</span> p <span class="fu">!</span> Person.name' <span class="fu">.=.</span> ph0')
(ph1, ()) <span class="ot">&lt;-</span> placeholder (\ph1' <span class="ot">-&gt;</span> on <span class="fu">$</span> p <span class="fu">!</span> Person.age' <span class="fu">.=.</span> ph1')
(ph2, ()) <span class="ot">&lt;-</span> placeholder (\ph2' <span class="ot">-&gt;</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">-&gt;</span> b)
<span class="ot">=&gt;</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Placeholders</span> a <span class="ot">-&gt;</span> <span class="dt">Placeholders</span> b
<span class="ot">(|*|) ::</span> <span class="dt">Placeholders</span> (a <span class="ot">-&gt;</span> b) <span class="ot">-&gt;</span> <span class="dt">Placeholders</span> a <span class="ot">-&gt;</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">=&gt;</span> (<span class="dt">Projection</span> c t <span class="ot">-&gt;</span> m a) <span class="ot">-&gt;</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">&lt;-</span> query person
b <span class="ot">&lt;-</span> query birthday
(ph, ()) <span class="ot">&lt;-</span> placeholder (\ph' <span class="ot">-&gt;</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">&lt;-</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">&gt;&lt;</span>
2014-12-25 04:18:33 +03:00
my <span class="fu">!</span> family' <span class="fu">&gt;&lt;</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">=&gt;</span> <span class="dt">ListProjection</span> (<span class="dt">Projection</span> <span class="dt">Exists</span>) r <span class="ot">-&gt;</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">=&gt;</span> [t] <span class="ot">-&gt;</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">=&gt;</span> <span class="dt">Relation</span> () r
<span class="ot">-&gt;</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">=&gt;</span> p t <span class="ot">-&gt;</span> <span class="dt">ListProjection</span> p t <span class="ot">-&gt;</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">=&gt;</span> <span class="dt">UniqueRelation</span> () c r
<span class="ot">-&gt;</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>