2008 lines
50 KiB
Text
2008 lines
50 KiB
Text
|
{
|
|||
|
"cells": [
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"- Each type of **Optic** comes with a set of compatible **actions**.\n",
|
|||
|
"\n",
|
|||
|
"Lenses have the following concrete gaurantees.\n",
|
|||
|
"\n",
|
|||
|
"* A Lens focuses (i.e selects) a single piece of data within a larger structure.\n",
|
|||
|
"* A Lens must **never fail** to **get** or **modify** that focus.\n",
|
|||
|
"\n",
|
|||
|
"These constraints unlock a few **actions** we can perform on lenses.\n",
|
|||
|
"\n",
|
|||
|
"* We can use a lens to **view** the **focus** within a structure.\n",
|
|||
|
"* We can use a lens to **set** the **focus** within a structure.\n",
|
|||
|
"* We can use a lens to **modify** the **focus** within a structure."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 14,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"\"hello\""
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"{-# 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",
|
|||
|
"view (_2 . _1) (42, (\"hello\", False))\n",
|
|||
|
"\n",
|
|||
|
"-- view is the action\n",
|
|||
|
"-- (_2 . _1) is the path\n",
|
|||
|
"-- (42, (\"hello\", False)) is the structure\n",
|
|||
|
"-- \"hello\" is the focus"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Exercises - Optic Anatomy"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 16,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"2"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"(False,Left \"new\")"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"\"TESTING ONE two three\""
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"\"supercalifragilisticexpialidocious\""
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"view (_1 . _2) ((1, 2), 3)\n",
|
|||
|
"\n",
|
|||
|
"-- view is the action\n",
|
|||
|
"-- (_1 . _2) is the path. Focus on the 1st member of tuple and then the 2nd member of 1st member\n",
|
|||
|
"-- ((1, 2), 3) is the structure\n",
|
|||
|
"-- 2 is the focus\n",
|
|||
|
"\n",
|
|||
|
"set (_2 . _Left) \"new\" (False, Left \"old\")\n",
|
|||
|
"\n",
|
|||
|
"-- set is the action\n",
|
|||
|
"-- (_2 . _Left) is the path\n",
|
|||
|
"-- (False, Left \"Old\") is the structure\n",
|
|||
|
"-- \"old\" is the focus\n",
|
|||
|
"\n",
|
|||
|
"over (taking 2 worded . traversed) C.toUpper \"testing one two three\"\n",
|
|||
|
"\n",
|
|||
|
"-- over is the action\n",
|
|||
|
"-- (taking 2 worded . traversed) is the path\n",
|
|||
|
"-- \"testing one two three\"\n",
|
|||
|
"-- \"testing one\" is the focus\n",
|
|||
|
"\n",
|
|||
|
"foldOf (both . each) ([\"super\", \"cali\"],[\"fragilistic\", \"expialidocious\"])\n",
|
|||
|
"\n",
|
|||
|
"-- foldOf is the action\n",
|
|||
|
"-- (both . each) is the path\n",
|
|||
|
"-- The rest is the structure"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Lens Actions\n",
|
|||
|
"\n",
|
|||
|
"### Viewing through lenses"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 25,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>_1 :: forall s t a b (f :: * -> *). (Field1 s t a b, Functor f) => (a -> f b) -> s -> f t</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"_1 :: forall s t a b (f :: * -> *). (Field1 s t a b, Functor f) => (a -> f b) -> s -> f t"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>Lens' :: * -> * -> *</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"Lens' :: * -> * -> *"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>Lens :: * -> * -> * -> * -> *</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"Lens :: * -> * -> * -> * -> *"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>_2 :: forall s t a b (f :: * -> *). (Field2 s t a b, Functor f) => (a -> f b) -> s -> f t</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"_2 :: forall s t a b (f :: * -> *). (Field2 s t a b, Functor f) => (a -> f b) -> s -> f t"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>view :: forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"view :: forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"'a'"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"'b'"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
":t _1\n",
|
|||
|
"\n",
|
|||
|
":k Lens'\n",
|
|||
|
":k Lens\n",
|
|||
|
"\n",
|
|||
|
"-- _1 :: Lens' (a, b) a\n",
|
|||
|
"-- (a, b) --> Type of structure\n",
|
|||
|
"-- a --> Focus within it\n",
|
|||
|
"\n",
|
|||
|
":t _2\n",
|
|||
|
"\n",
|
|||
|
":t view\n",
|
|||
|
"\n",
|
|||
|
"-- A lens on it's own isn't enough. We need an action to perform on it.\n",
|
|||
|
"\n",
|
|||
|
"-- view :: Lens' s a -> s -> a\n",
|
|||
|
"-- Get the path's focus from within the structure\n",
|
|||
|
"\n",
|
|||
|
"view _1 ('a', 'b')\n",
|
|||
|
"\n",
|
|||
|
"view _2 ('a', 'b')"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"### Setting through a lens"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 28,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>set :: forall s t a b. ASetter s t a b -> b -> s -> t</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"set :: forall s t a b. ASetter s t a b -> b -> s -> t"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>over :: forall s t a b. ASetter s t a b -> (a -> b) -> s -> t</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"over :: forall s t a b. ASetter s t a b -> (a -> b) -> s -> t"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"('x','b')"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"(100,2)"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"-- set :: Lens' s a -> a -> s -> s\n",
|
|||
|
"-- Set a new value at the path’s focus, leaving the rest of the structure unaltered.\n",
|
|||
|
"\n",
|
|||
|
"-- over :: Lens' s a -> (a -> a) -> s -> s\n",
|
|||
|
"-- Modify the focus of a path by running a function over it, altering it in-place and leaving the\n",
|
|||
|
"-- rest of the structure unaltered.\n",
|
|||
|
"\n",
|
|||
|
":t set\n",
|
|||
|
":t over\n",
|
|||
|
"\n",
|
|||
|
"set _1 'x' ('a', 'b')\n",
|
|||
|
"\n",
|
|||
|
"over _1 (*100) (1, 2)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Exercises - Lens Actions"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 30,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"'c'"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"(False,20)"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"-- 1. Find structure & focus in the following lens\n",
|
|||
|
"\n",
|
|||
|
"-- Lens' (Bool, (Int, String)) Int\n",
|
|||
|
"\n",
|
|||
|
"-- (Bool, (Int, String)) is the structure\n",
|
|||
|
"-- Focus is Int, the 1st member of the 2nd member of the complete structure\n",
|
|||
|
"\n",
|
|||
|
"-- 2. Write the type signature of a Lens with the structure (Char, Int) and the focus Char\n",
|
|||
|
"\n",
|
|||
|
"-- Lens' (Char, Int) Char\n",
|
|||
|
"\n",
|
|||
|
"-- 3. Name three actions we can use on a Lens\n",
|
|||
|
"\n",
|
|||
|
"-- set\n",
|
|||
|
"-- view\n",
|
|||
|
"-- over\n",
|
|||
|
"\n",
|
|||
|
"-- 4\n",
|
|||
|
"\n",
|
|||
|
"view _3 ('a', 'b', 'c')\n",
|
|||
|
"\n",
|
|||
|
"over _2 (*10) (False, 2)"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Lenses and records\n",
|
|||
|
"\n",
|
|||
|
"* Lenses subsume the accessor pattern in other languages."
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 47,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>lens :: forall (f :: * -> *) s a b t. Functor f => (s -> a) -> (s -> b -> t) -> (a -> f b) -> s -> f t</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"lens :: forall (f :: * -> *) s a b t. Functor f => (s -> a) -> (s -> b -> t) -> (a -> f b) -> s -> f t"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>Lens :: * -> * -> * -> * -> *</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"Lens :: * -> * -> * -> * -> *"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>Lens' :: * -> * -> *</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"Lens' :: * -> * -> *"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"-- Just changed the names from the example in the book\n",
|
|||
|
"data Name = \n",
|
|||
|
" Name { _name :: String\n",
|
|||
|
" , _age :: Int\n",
|
|||
|
" } deriving (Show)\n",
|
|||
|
" \n",
|
|||
|
"-- lens :: (s -> a) -> (s -> b -> t) -> Lens s t a b\n",
|
|||
|
"-- lens :: (s -> a) -> (s -> a -> s) -> Lens' s a\n",
|
|||
|
"\n",
|
|||
|
":t lens\n",
|
|||
|
":k Lens\n",
|
|||
|
":k Lens'\n",
|
|||
|
"\n",
|
|||
|
"-- Whenever you see 's' in a Lens thing 'structure' and when you see 'a', think 'focus'.\n",
|
|||
|
"\n",
|
|||
|
"-- getAge :: s -> a\n",
|
|||
|
"getAge :: Name -> Int\n",
|
|||
|
"getAge = _age\n",
|
|||
|
"\n",
|
|||
|
"-- setAge :: s -> a -> s\n",
|
|||
|
"setAge :: Name -> Int -> Name\n",
|
|||
|
"setAge name newAge = name { _age = newAge }\n",
|
|||
|
"\n",
|
|||
|
"numAge :: Lens' Name Int\n",
|
|||
|
"numAge = lens getAge setAge"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Exercises - Records Part One"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 62,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"31"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"Name {_name = \"Sanchayan Maity\", _age = 32}"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"Name {_name = \"Sanchayan Maity\", _age = 34}"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"Name {_name = \"Sanchayan Maity\", _age = 34}"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"\"Sanchayan Maity\""
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"Name {_name = \"Foo\", _age = 31}"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"Name {_name = \"Boo Sanchayan Maity\", _age = 31}"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"-- 1. The structure and focus of a lens are typically represented by which letters in type signature\n",
|
|||
|
"-- s and a respectively\n",
|
|||
|
"\n",
|
|||
|
"-- 2. Which two components are required to create a lens\n",
|
|||
|
"-- getter and setter\n",
|
|||
|
"\n",
|
|||
|
"-- Implement the following Lens\n",
|
|||
|
"\n",
|
|||
|
"-- name :: Lens' Name String\n",
|
|||
|
"\n",
|
|||
|
"getName :: Name -> String\n",
|
|||
|
"getName = _name\n",
|
|||
|
"\n",
|
|||
|
"setName :: Name -> String -> Name\n",
|
|||
|
"setName name newName = name { _name = newName }\n",
|
|||
|
"\n",
|
|||
|
"name :: Lens' Name String\n",
|
|||
|
"name = lens getName setName\n",
|
|||
|
"\n",
|
|||
|
"myName :: Name\n",
|
|||
|
"myName = Name { _name = \"Sanchayan Maity\"\n",
|
|||
|
" , _age = 31 } \n",
|
|||
|
" \n",
|
|||
|
"-- Getting, setting & modifying with a field lens\n",
|
|||
|
"\n",
|
|||
|
"-- For Age field\n",
|
|||
|
"view numAge myName\n",
|
|||
|
"set numAge 32 myName\n",
|
|||
|
"over numAge (+3) myName\n",
|
|||
|
"set numAge (view numAge myName + 3) myName\n",
|
|||
|
"\n",
|
|||
|
"-- For Name field\n",
|
|||
|
"view name myName\n",
|
|||
|
"set name \"Foo\" myName\n",
|
|||
|
"over name (\"Boo \" ++) myName"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Automatically generating field names"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 67,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>name :: forall (f :: * -> *). Functor f => (String -> f String) -> Ship -> f Ship</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"name :: forall (f :: * -> *). Functor f => (String -> f String) -> Ship -> f Ship"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>numCrew :: forall (f :: * -> *). Functor f => (Int -> f Int) -> Ship -> f Ship</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"numCrew :: forall (f :: * -> *). Functor f => (Int -> f Int) -> Ship -> f Ship"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>getNumCrew :: Ship -> Int</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"getNumCrew :: Ship -> Int"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"data Ship = \n",
|
|||
|
" Ship { _name :: String\n",
|
|||
|
" , _numCrew :: Int \n",
|
|||
|
" } deriving (Show)\n",
|
|||
|
"\n",
|
|||
|
"makeLenses ''Ship\n",
|
|||
|
"\n",
|
|||
|
":t name\n",
|
|||
|
":t numCrew\n",
|
|||
|
":t getNumCrew"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Exercises - Records Part Two"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 72,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"-- data Inventory = \n",
|
|||
|
"-- Inventory { _wand :: Wand\n",
|
|||
|
"-- , _book :: Book\n",
|
|||
|
"-- , _potions :: [Potion] }\n",
|
|||
|
"\n",
|
|||
|
"-- makeLenses ''Inventory\n",
|
|||
|
"\n",
|
|||
|
"-- Lenses generated would be\n",
|
|||
|
"\n",
|
|||
|
"-- wand\n",
|
|||
|
"-- book\n",
|
|||
|
"-- potions\n",
|
|||
|
"-- getWand\n",
|
|||
|
"-- getBook\n",
|
|||
|
"-- getPotions\n",
|
|||
|
"-- setWand\n",
|
|||
|
"-- setBook\n",
|
|||
|
"-- setPotions\n",
|
|||
|
"\n",
|
|||
|
"-- gazork :: Functor f => (Spuzz -> f Spuzz) -> Chumble -> f Chumble\n",
|
|||
|
"-- gazork :: Lens' Chumble Spuzz\n",
|
|||
|
"\n",
|
|||
|
"data Pet = Pet \n",
|
|||
|
" { _petName :: String\n",
|
|||
|
" , _petType :: String\n",
|
|||
|
" }\n",
|
|||
|
" \n",
|
|||
|
"makeLenses ''Pet\n",
|
|||
|
"\n",
|
|||
|
"getPetName :: Pet -> String\n",
|
|||
|
"getPetName = view petName"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"### Lens is an optic which **always** accesses **exactly** one focus"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"### Is it a Lens?\n",
|
|||
|
"\n",
|
|||
|
"* second :: Lens' (a, b, c) b\n",
|
|||
|
"\n",
|
|||
|
"* inMaybe :: Lens' (Maybe a) a\n",
|
|||
|
"\n",
|
|||
|
"* left :: Lens' (Either a b) a\n",
|
|||
|
"\n",
|
|||
|
"* listThird :: Lens' [a] a\n",
|
|||
|
"\n",
|
|||
|
"* Can you write a lens which focuses the second element of a tuple if the Bool in the first slot is True and focuses the third element if it’s False ? conditional :: Lens' (Bool, a, a) a\n",
|
|||
|
"\n",
|
|||
|
"* Consider the below data type. Is it possible to have a lens msg :: Lens' Err String"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 75,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [],
|
|||
|
"source": [
|
|||
|
"data Err = \n",
|
|||
|
" ReallyBadError { _msg :: String }\n",
|
|||
|
" | ExitCode { _code :: Int }\n"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Lens Laws\n",
|
|||
|
"\n",
|
|||
|
"1. You get back what you set\n",
|
|||
|
"2. Setting back what you got doesn't do anything\n",
|
|||
|
"3. Setting twice is the same as setting once"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"## Virtual Fields"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "code",
|
|||
|
"execution_count": 82,
|
|||
|
"metadata": {},
|
|||
|
"outputs": [
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/html": [
|
|||
|
"<style>/* Styles used for the Hoogle display in the pager */\n",
|
|||
|
".hoogle-doc {\n",
|
|||
|
"display: block;\n",
|
|||
|
"padding-bottom: 1.3em;\n",
|
|||
|
"padding-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-code {\n",
|
|||
|
"display: block;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-text {\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-name {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-head {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-sub {\n",
|
|||
|
"display: block;\n",
|
|||
|
"margin-left: 0.4em;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-package {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-module {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".hoogle-class {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".get-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"white-space: pre-wrap;\n",
|
|||
|
"}\n",
|
|||
|
".show-type {\n",
|
|||
|
"color: green;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"margin-left: 1em;\n",
|
|||
|
"}\n",
|
|||
|
".mono {\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-style: italic;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"display: block;\n",
|
|||
|
"}\n",
|
|||
|
"#unshowable {\n",
|
|||
|
"color: red;\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
".err-msg.in.collapse {\n",
|
|||
|
"padding-top: 0.7em;\n",
|
|||
|
"}\n",
|
|||
|
".highlight-code {\n",
|
|||
|
"white-space: pre;\n",
|
|||
|
"font-family: monospace;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-warning { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: rgb(200, 130, 0);\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-error { \n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"color: red;\n",
|
|||
|
"}\n",
|
|||
|
".suggestion-name {\n",
|
|||
|
"font-weight: bold;\n",
|
|||
|
"}\n",
|
|||
|
"</style><span class='get-type'>celsius :: forall (f :: * -> *). Functor f => (Float -> f Float) -> Temperature -> f Temperature</span>"
|
|||
|
],
|
|||
|
"text/plain": [
|
|||
|
"celsius :: forall (f :: * -> *). Functor f => (Float -> f Float) -> Temperature -> f Temperature"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"7.0"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"Temperature {_location = \"Bangalore\", _celsius = 13.5}"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"Temperature {_location = \"Bangalore\", _celsius = 17.0}"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"44.6"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"Temperature {_location = \"Bangalore\", _celsius = 13.5}"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
},
|
|||
|
{
|
|||
|
"data": {
|
|||
|
"text/plain": [
|
|||
|
"Temperature {_location = \"Bangalore\", _celsius = 17.0}"
|
|||
|
]
|
|||
|
},
|
|||
|
"metadata": {},
|
|||
|
"output_type": "display_data"
|
|||
|
}
|
|||
|
],
|
|||
|
"source": [
|
|||
|
"data Temperature = \n",
|
|||
|
" Temperature { _location :: String\n",
|
|||
|
" , _celsius :: Float\n",
|
|||
|
" } deriving (Show)\n",
|
|||
|
" \n",
|
|||
|
"makeLenses ''Temperature\n",
|
|||
|
"\n",
|
|||
|
":t celsius\n",
|
|||
|
"\n",
|
|||
|
"let temp = Temperature \"Bangalore\" 7.0\n",
|
|||
|
"\n",
|
|||
|
"view celsius temp\n",
|
|||
|
"set celsius 13.5 temp\n",
|
|||
|
"over celsius (+10) temp\n",
|
|||
|
"\n",
|
|||
|
"celsiusToFahrenheit :: Float -> Float\n",
|
|||
|
"celsiusToFahrenheit c = (c * (9/5)) + 32\n",
|
|||
|
"\n",
|
|||
|
"fahrenheitToCelsius :: Float -> Float\n",
|
|||
|
"fahrenheitToCelsius f = (f - 32) * (5/9)\n",
|
|||
|
"\n",
|
|||
|
"fahrenheit :: Lens' Temperature Float\n",
|
|||
|
"fahrenheit = lens getter setter\n",
|
|||
|
" where\n",
|
|||
|
" getter = celsiusToFahrenheit . view celsius\n",
|
|||
|
" setter temp f = set celsius (fahrenheitToCelsius f) temp\n",
|
|||
|
" \n",
|
|||
|
"view fahrenheit temp\n",
|
|||
|
"set fahrenheit 56.3 temp\n",
|
|||
|
"over fahrenheit (+18) temp"
|
|||
|
]
|
|||
|
},
|
|||
|
{
|
|||
|
"cell_type": "markdown",
|
|||
|
"metadata": {},
|
|||
|
"source": [
|
|||
|
"Note: TODO: The exercises on laws & virtual fields"
|
|||
|
]
|
|||
|
}
|
|||
|
],
|
|||
|
"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
|
|||
|
}
|