lambda.either
Either data type
- API:
const Either = Right Left fromNullable of try: tryCatch moduleexports = Either
- Examples:
When to use what? - Code that never fails!
const Task Either Box compose map fold chain ap fork trace = const fs = // we are using Task in order not to grab the state directly// by doing so we isolate the side-effects and make our app more safely // Use Task for side-effects: console.log, process.arg, http calls, db calls, read/write -> ASYNCHRONOUS CODEconst argv = const httpGet = const readFile = const file = // Use Eiter.try for JSON.parse/JSON.stringify -> SYNCHRONOUS CODEconst parse = Either const readFileSync = Either const result = result // Use Either.fromNullable when you are trying to get properties out of an object object.property const first = Either const name = const myName = const herName = myNameherName
Either.fromNullable - Code that never fails!
const Task Either prop compose trace map fold chain = const findColor = red: '#ff4444' green: '#36599' blue: '#fff68f' name const getColor = Eitherconst sliceBy = strconst upperCaseValue = strconst reportError = 'no color'const showResult = const sliceByTwo = const result = // 36599 // FF4444 // FFF68F // no color // no color // no color
ap && chain (Reigth/Left.chain || Right/Left.ap) - Code that never fails
const Task Either prop compose trace map fold chain = const fs = // Important: If you'll try to get a non-existing property out of the object, //the app would not return undefined it will return 3000 as default value of the error function, defined in showResult()const getProperty = Either const readFile = Eitherconst parseJSON = Eitherconst isPortAvailable = const parse = const showResult = const result = // 8888 // 3000
Currying with Types (Boxes & Either)
const Box = const add = x + yconst res = console//---------------------------------- // ----------------------------------const Task Either prop compose trace map fold chain ap = const $ = Either const getScreenSize = screen - headheight + footheight const result = console
ap - safe and concurent IO operations - Code that never fails
const Task Either prop compose trace map fold chain ap = const request = const url1 = 'https://jsonplaceholder.typicode.com/posts/4'const url2 = 'https://jsonplaceholder.typicode.com/posts/2' const e = 'error'const identity = xconst getTitle = Eitherconst getId = Either const reportHeader = `Report: compared to ` const reportId = `Report: compared to ` const parse = Either const httpGet = const res = // Report: eum et est occaecati compared to qui est esse // Report: 4 compared to 2
ap Redux - concurrent IO operations - Code that never fails
const Task Either prop compose trace map fold chain ap = const request = const update = msgtype === 'UPDATE' ? ...model report: msgpayload : msgtype === 'ERROR' ? ...model error: msgerror : model const dispatch = { let model = {} model = model console} const updateModelMsg = type: 'UPDATE' payload const updateModelErrorMsg = type: 'ERROR' error const url1 = 'https://jsonplaceholder.typicode.com/posts/4'const url2 = 'https://jsonplaceholder.typicode.com/posts/2' const e = const identity = xconst getTitle = Eitherconst getId = Either const reportHeader = `Report: compared to ` const reportId = `Report: compared to ` const parse = Either const httpGet = const res = // UPDATED MODEL { report: 'Report: 4 compared to 2' }// UPDATED MODEL { report: 'Report: eum et est occaecati compared to qui est esse' }
safe I/O Operations with Parsing - Code that never fails
const Task Either prop compose trace map fold chain ap fork = const fs = const readFile = const writeFile = const writeToConfigTwo = const parse = Eitherconst stringify = Either const getProperty = Task const eitherToTask = e const error = consoleconst success = console const transformation =
Traversable with Lists
const Task = const fs = const readFile = const List = { return xs } const files = files
Example
const map prop compose trace = const users = name: 'Dimitri' isAdmin: true name: 'John' isAdmin: true name: 'Mike' isAdmin: false const names = console // [ 'Dimitri', 'John', 'Mike' ] const message = Records: name: 'Dimitri' isAdmin: true name: 'John' isAdmin: true name: 'Mike' isAdmin: false const extractNamesFromMessage = console// AFTER PLUCK: [// {// "name": "Dimitri",// "isAdmin": true// },// {// "name": "John",// "isAdmin": true// },// {// "name": "Mike",// "isAdmin": false// }// ]//[ 'Dimitri', 'John', 'Mike' ] const filterNamesFromMessage = console// [ { name: 'Dimitri', isAdmin: true } ]
Task - Lazy Evaluation / Isolation of Side Effects
const Task = // pure functionconst readFile = // pure functionconst writeFile = // pure functionconst app = // impure function with side effectsapp
Lifting a value into a type
const f = x const res = Taskres // hello!!! Either // hello!!!
Try/Catch Examples
const Either = const fs = const tryCatch = { try return Either catch e return Either } const getPort = const res =
Try with Either.try(f)
const parse = Either const eitherToTask = e const findPost = const main = Task id
Either - Instead of If/Else + Composition
const fromNullable = x !== null ? Either : Either // You can also import Either.fromNullable() and use it instead of fromNullable()const findColor = const result =
Either - Instead of If/Else + Composition
const Task Either prop compose trace map fold chain = const fromNullable Right Left = Either const dispatch = consoleconst getItem = const someAction2 = data const toUpperCase = str const someAction3 = data const prepeareAction = const prepareNewAction = // comes from the err function -> the application runs without exiting // TypeError: Cannot read property 'item' of null
deepFreeze Examples - Immutable data
const expect = const deepFreeze = const addCounter = ...list 0 const removeCounter = ...list ...list const incrementCounter = ...list listindex + 1 ...list const testAddCounter = 0 const testRemoveCounter = 0 20 const testIncrementCounter = 0 11 20
Some other examples
const fromNullable = x !== null ? Either : Either const tryCatch = { try return Either catch e return Either } // imperative codeconst openSite = { if current_user return else return } // declarative codeconst openSite = { } // imperative codeconst getPrefs = { if userpremium return else return defaultPrefs } // declarative codeconst getPrefs = userpremium ? : // imperative codeconst streetName = { const address = useraddress if address const street = addressstreet if street return streetname return 'no street!'} // declarative codeconst streetName = // imperative codeconst concatUniq = { const found = ys0 return found ? ys : ys} // declarative codeconst concatUniq = // imperative codeconst wrapExamples = { if examplepreviewPath try examplepreview = fs catch e return example} const readFile = // declarative codeconst wrapExamples = { } // imperative codeconst parseDbUrl = { try const c = JSON ifcurl return curl catche return null } // declarative codeconst parseDbUrl = { }