212 lines
5.5 KiB
Text
212 lines
5.5 KiB
Text
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "markdown",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Optics\n",
|
|
"\n",
|
|
"## What are optics?\n",
|
|
"\n",
|
|
"Lenses, Folds, Traversals, Prisms and Isos are all types of Optics.\n",
|
|
"\n",
|
|
"## Strengths\n",
|
|
"\n",
|
|
"1. Composition\n",
|
|
"2. Separation of Concerns\n",
|
|
"3. Concision\n",
|
|
"4. Enforcing interface boundaries\n",
|
|
"5. Principled and mature ecosystem\n",
|
|
"\n",
|
|
"## Weaknesses\n",
|
|
"\n",
|
|
"1. Type-errors\n",
|
|
"2. Complex Implementation\n",
|
|
"3. Vast number of combinators\n",
|
|
"\n",
|
|
"## Some examples\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 14,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"30"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[\"This one t...\",\"Nuff said.\",\"This is a ...\"]"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"27"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"\"Why Is A Raven Like A Writing Desk\""
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"(Just 300,Left (\"hello\",[1300,1500,1700]))"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[1,8,3,6,5,4,7,2]"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"(\"eee\",\"hno\",\"orttw\")"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"[3,0,1,6]"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
},
|
|
{
|
|
"data": {
|
|
"text/plain": [
|
|
"What is your name?\n",
|
|
"What is your quest?\n",
|
|
"What is your favourite color?\n",
|
|
"(\"Sir Galahad\",\"To seek the holy grail\",\"Black I think\")"
|
|
]
|
|
},
|
|
"metadata": {},
|
|
"output_type": "display_data"
|
|
}
|
|
],
|
|
"source": [
|
|
"-- Required Language Extensions and imports\n",
|
|
"\n",
|
|
"{-# LANGUAGE TemplateHaskell #-}\n",
|
|
"{-# LANGUAGE FlexibleInstances #-}\n",
|
|
"{-# LANGUAGE FlexibleContexts #-}\n",
|
|
"{-# LANGUAGE RankNTypes #-}\n",
|
|
"{-# LANGUAGE ScopedTypeVariables #-}\n",
|
|
"{-# LANGUAGE TypeApplications #-}\n",
|
|
"{-# LANGUAGE TypeFamilies #-}\n",
|
|
"{-# LANGUAGE InstanceSigs #-}\n",
|
|
"\n",
|
|
"import Control.Lens\n",
|
|
"import Numeric.Lens\n",
|
|
"import Data.Bits.Lens\n",
|
|
"import Data.Data.Lens\n",
|
|
"\n",
|
|
"import Control.Applicative\n",
|
|
"import Data.Char as C\n",
|
|
"import qualified Data.Map as M\n",
|
|
"import qualified Data.Set as S\n",
|
|
"import qualified Data.Text as T\n",
|
|
"import qualified Data.List as L\n",
|
|
"\n",
|
|
"-- Below examples are taken from Chris Penner's Optics by Example\n",
|
|
"\n",
|
|
"-- View nested fields of some record type\n",
|
|
"\n",
|
|
"--- view (address . country) person\n",
|
|
"---\"Canada\"\n",
|
|
"\n",
|
|
"-- Update portions of immutable data structures\n",
|
|
"\n",
|
|
"-- set _3 False ('a', 'b', 'c')\n",
|
|
"-- ('a', 'b', False)\n",
|
|
"\n",
|
|
"-- These selectors compose!\n",
|
|
"-- We can perform a task over deeply nested subsets of data.\n",
|
|
"-- Let's sum all numbers which in a 'Left' within the right half of each tuple\n",
|
|
"\n",
|
|
"sumOf (folded . _2 . _Left) [(True, Left 10), (False, Right \"pepporoni\"), (True, Left 20)]\n",
|
|
"\n",
|
|
"let stories = [\"This one time at band camp\", \"Nuff said.\", \"This is a short story\"]\n",
|
|
"\n",
|
|
"over (traversed . filtered ((>10) . length)) (\\story -> take 10 story ++ \"...\") stories\n",
|
|
"\n",
|
|
"-- Summarize a list of numbers, subtracting the 'Left's, adding the 'Right's!\n",
|
|
"\n",
|
|
"sumOf (folded . beside negated id) [Left 1, Right 10, Left 2, Right 20]\n",
|
|
"\n",
|
|
"-- Capitalize each word in a sentence\n",
|
|
"\"why is a raven like a writing desk\" & worded . _head %~ toUpper\n",
|
|
"\n",
|
|
"-- Multiply every Integer by 100 no matter where they are in the structure:\n",
|
|
"(Just 3, Left (\"hello\", [13, 15, 17])) & biplate *~ 100\n",
|
|
"\n",
|
|
"-- Reverse the ordering of all even numbers in a sequence.\n",
|
|
"-- We leave the odd numbers alone!\n",
|
|
"[1, 2, 3, 4, 5, 6, 7, 8] & partsOf (traversed . filtered even) %~ reverse\n",
|
|
"\n",
|
|
"-- Sort all the characters in all strings, across word boundaries!\n",
|
|
"(\"one\", \"two\", \"three\") & partsOf (each . traversed) %~ L.sort\n",
|
|
"\n",
|
|
"-- Flip the 2nd bit of each number to a 0\n",
|
|
"[1, 2, 3, 4] & traversed . bitAt 1 %~ not\n",
|
|
"\n",
|
|
"-- Prompt the user with each question in a tuple,\n",
|
|
"-- then return the tuple with each prompt replaced with the user's input,\n",
|
|
"let prompts = ( \"What is your name?\"\n",
|
|
" , \"What is your quest?\"\n",
|
|
" , \"What is your favourite color?\"\n",
|
|
" )\n",
|
|
"prompts & each %%~ (\\prompt -> putStrLn prompt >> getLine)"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Haskell",
|
|
"language": "haskell",
|
|
"name": "haskell"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": "ihaskell",
|
|
"file_extension": ".hs",
|
|
"name": "haskell",
|
|
"pygments_lexer": "Haskell",
|
|
"version": "8.6.5"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|