SlideShare uma empresa Scribd logo
1 de 46
Baixar para ler offline
August 7, 2017
Tom Prior
www.prigrammer.com
@priortd
F# Delight
Our Sponsors
Getting started – F# interactive FSI
https://www.microsoft.com/net/download/core
dotnet new console -lang f# -o MyConsoleApp
cd MyConsoleApp
dotnet restore
code .
Create fsx file and start
executing code with f#
interactive!
Just highlight and press
Alt-Enter
The Delights
• Simplicity
• Immutability
• Pattern matching
• Encoding logic in types
• Automatic currying – all functions are one arg functions
• High level transformations and functional pipelines
Immutability – let bindings
let x = 2
Evaluated in FSI…
val x : int = 2
Will this increment x ??
Evaluated in FSI…
val x : int = 2
val it : bool = false
let x = 2
x = x + 1
Specifying Mutability
Evaluated in FSI…
val mutable y : int = 3
val it : unit = ()
x <- x + 1 //won’t compile as x not mutable.
let mutable y = 2
y <- y + 1
Tuples
let p = ("Tom", 38)
fst p
Evaluated in FSI ….
val p : string * int = ("Tom", 38)
val it : string = "Tom"
Immutability – OO Classes
type Person(name:string) =
member p.Name = name
Immutability – Records
type Person = {
Name : string
Age : int }
let p = { Name = "Tom"; Age = 56 }
Evaluated in FSI…
type Person =
{Name: string;
Age: int;}
val p : Person = {Name = "Tom";
Age = 56;}
Evaluated in FSI…
val it : string = "Tom"
//won't compile as records are immutable.
p.Name <- "Jack"
p.Name
Immutable Collections
Evaluated in FSI…
val numbers : int list = [1; 2; 3; 4]
open FSharp.Collections
let numbers = [ 1; 2; 3; 4 ]
//won't compile becuase lists are immutable
numbers.[2] <- 7
Arrays still mutable
Evaluated in FSI…
val names : string [] = [|"tom"; "eleanor"|]
val it : string = "tom"
let names = [| "tom"; "eleanor" |]
names.[0]
names.[0] <- "Myles"
names.[0]
Evaluated in FSI…
val it : string = "Myles"
Pattern matching
Evaluated in FSI…
val person : string * int = ("Tom", 38)
val name : string = "Tom"
val age : int = 38
let person = ("Tom", 38)
let (name, age) = person
Match expressions
Evaluated in FSI…
val getName : 'a * 'b -> 'a
val person : string * int = ("Tom", 38)
val it : string = "Tom"
let getName person =
match person with
| (name, age) -> name
let person = ("Tom", 38)
getName person
Pattern matching on records
Evaluated in FSI…
type Person =
{Name: string;
Age: int;}
val p : Person = {Name = "Tom";
Age = 38;}
val personName : string = "Tom"
type Person = { Name : string; Age : int }
let p = { Name = "Tom"; Age = 38 }
let { Name = personName; Age = _ } = p
Pattern matching on lists
let l = [ 1; 2; 3 ]
1
2
3
[]
//l can be re-written as
let l = 1 :: 2 :: 3 :: []
Evaluated in FSI…
val l : int list = [1; 2; 3]
val getFirst : list:'a list -> 'a
val it : int = 1
let l = 1 :: 2 :: 3 :: []
let getFirst list =
match list with // warning if not all patterns covered
| x :: xs -> x
| [] -> failwith "cannot get first on an empty list"
// you wouldn't actually do this - this would return an option
instead - will cover this shortly.
getFirst l
Discriminated Unions
type Drummer = Drummer of string
type BassPlayer = BassPlayer of string
type SaxPlayer = SaxPlayer of string
type PianoPlayer = PianoPlayer of string
type JazzBand =
| PianoTrio of PianoPlayer * BassPlayer * Drummer
| SaxTrio of SaxPlayer * BassPlayer * Drummer
| Quartet of SaxPlayer * PianoPlayer * BassPlayer * Drummer
Simplified…
let getBandLeader (jazzband: JazzBand) =
match jazzband with
| PianoTrio(PianoPlayer(ppn), BassPlayer(bassPlayerName), Drummer(dn)) -> ppn
| SaxTrio(SaxPlayer(spn), BassPlayer(bpn), Drummer(dn)) -> spn
| Quartet(SaxPlayer(spn), PianoPlayer(name), BassPlayer(bpn), Drummer(dn)) -> spn
let getBandLeader (jazzband: JazzBand) =
match jazzband with
| PianoTrio(PianoPlayer(pianoPlayerName), _, _) -> pianoPlayerName
| SaxTrio(SaxPlayer(saxPlayerName), _, _) -> saxPlayerName
| Quartet(SaxPlayer(saxPlayerName), _, _, _) -> saxPlayerName
Making illegal states unrepresentable
From a different module ….
type Drummer = private Drummer of string
let createDrummer name =
// do some lookup to validate that this person is actually
// a drummer
let drummers = [ "Max Roache"; "Elvin Jones"; "Tony Williams" ]
if List.contains name drummers then
Some (Drummer name)
else None
// won't compile because the union case fields are not accessible
let drummer = Drummer("tom")
Making illegal states unrepresentable
Evaluate in FSI…
let drummer = createDrummer "tom"
val drummer : Drummer option = None
let drummer = createDrummer "Max Roache"
Evaluate in FSI…
val drummer : Drummer option = Some Drummer "Max Roache"
Pattern matching private data constructors
let (|Drummer|) (Drummer name) = Drummer(name)
let getBandLeader (jazzband: JazzBand) =
match jazzband with
| PianoTrio(PianoPlayer(ppn), BassPlayer(bassPlayerName), Drummer(dn)) -> ppn
| SaxTrio(SaxPlayer(spn), BassPlayer(bpn), Drummer(dn)) -> spn
| Quartet(SaxPlayer(spn), PianoPlayer(name), BassPlayer(bpn), Drummer(dn)) -> spn
Automatic currying
type Message = {
Id : Guid
Payload : string
}
let addPrefix (prefix:string, message:Message) =
{ Id = message.Id
Payload = prefix + message.Payload }
Evaluate in FSI..
val addPrefix : prefix:string * message:Message -> Message
Automatic currying
Evaluate in FSI…
let message = { Id = Guid.NewGuid(); Payload = "my payload" }
let addPrefix' prefix =
fun message ->
{ message with
Payload = prefix + message.Payload }
addPrefix’ “hello "
val it : (Message -> Message) = <fun:it@3>
let addHelloPrefix = addPrefix’ “hello "
addHelloPrefix message
Evaluate in FSI…
val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038;
Payload = “hello my payload ";}
Automatic currying
Evaluate in FSI…
val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038;
Payload = "my prefix to my payload ";}
let addHelloPrefix = addPrefix’’ “hello "
addHelloPrefix message
Evaluate in FSI…
val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038;
Payload = “hello my payload ";}
let addPrefix'' prefix message =
{ message with
Payload = prefix + message.Payload }
addPrefix'' "my prefix to " message
Functional pipelines
Evaluate in FSI…
val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038;
Payload = “header:my payload:footer ";}
let addPostfix postfix message =
{ message with
Payload = message.Payload + postfix }
//hard to read with nested parens
let transformMessage message =
(addPostfix "footer" (addPrefix'' "header:" message))
let transformMessage' message =
message
|> addPrefix'' "header:"
|> addPostfix ":footer"
transformMessage' message
Functional pipelines
Evaluate in FSI…
val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038;
Payload = “header:my payload:footer ";}
let addPostfix postfix message =
{ message with
Payload = message.Payload + postfix }
//hard to read with nested parens
let transformMessage message =
(addPostfix "footer" (addPrefix'' "header:" message))
let transformMessage' message =
message
|> addPrefix'' "header:"
|> addPostfix ":footer"
transformMessage' message
Loops to high level transformations
h u z z a h
u z z a
h u z z u h
u z z u
z z
Imperative C# implementation
static bool IsPalindrome(string candidate)
{
var endIndex = candidate.Length - 1;
for(var i = 0; i < candidate.Length/2; i++)
{
if (candidate[i] != candidate[endIndex - i])
return false;
}
return true;
}
Imperative loop in F#
let palindromeWithWhileLoop (candidate:string) =
let endIndex = candidate.Length - 1
let mutable isPalindrome = true
let mutable i = 0
while i < candidate.Length/2 && isPalindrome do
if candidate.[i] <> candidate.[endIndex - i] then
isPalindrome <- false
i <- i + 1
isPalindrome
Lets remove the mutable variables
let palindromeWithRecursiveLoop (candidate:string) =
let endIndex = candidate.Length - 1
let rec loop i isPalindrome =
if i < candidate.Length/2 && isPalindrome then
loop (i + 1) (candidate.[i] = candidate.[endIndex - i])
else
isPalindrome
loop 0 true
Simplify with pattern matching
let rec isPalindrome candidate =
let exceptLast list = (list |> List.truncate (list.Length - 1))
match candidate with
| [] -> true
| [x] -> true
| [x1; x2] -> x1 = x2
| x1 :: xs -> x1 = List.last xs && xs |> exceptLast |> isPalindrome
Removing the imperative loop
let palindromeWithTryFind (candidate: string) =
candidate
|> Seq.mapi (fun index c -> (index, c))
|> Seq.tryFind (fun (index, c) ->
let indexFromEnd = (Seq.length candidate) - (index + 1)
indexFromEnd >= index && c <> candidate.[indexFromEnd])
|> Option.isNone
Transform only the palindromes
let toUppercasePalindromes candidates =
candidates
|> Seq.filter (fun candidate -> isPalindrome candidate)
|> Seq.map (fun palindrome -> palindrome.ToUpper())
Simplified…
let toUppercasePalindromes candidates =
candidates
|> Seq.filter isPalindrome
|> Seq.map (fun palindrome -> palindrome.ToUpper())
[ "anina"; "aninaa"; "aniina"; ""; "a"; "at"; "anireina" ]
|> toUppercasePalindromes |> Seq.toList
Evaluate in FSI…
val it : string list = ["ANINA"; "ANIINA"; ""; "A"]
Learning Resources
https://fsharpforfunandprofit.com/
Kit Eason’s courses on Pluralsight
Try hackerrank problems in F#
https://www.hackerrank.com/
https://www.pluralsight.com/courses/fsharp-jumpstart

Mais conteúdo relacionado

Mais procurados

Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script ProgrammingLin Yo-An
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Wen-Tien Chang
 
Ruby 程式語言簡介
Ruby 程式語言簡介Ruby 程式語言簡介
Ruby 程式語言簡介Wen-Tien Chang
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...takeoutweight
 
Template Haskell Tutorial
Template Haskell TutorialTemplate Haskell Tutorial
Template Haskell Tutorialkizzx2
 
Functional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperFunctional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperosfameron
 
Erlang Concurrency
Erlang ConcurrencyErlang Concurrency
Erlang ConcurrencyBarry Ezell
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009Jordan Baker
 
2 BytesC++ course_2014_c2_ flow of control
2 BytesC++ course_2014_c2_ flow of control 2 BytesC++ course_2014_c2_ flow of control
2 BytesC++ course_2014_c2_ flow of control kinan keshkeh
 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby HackersEleanor McHugh
 
Declarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeDeclarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeKevlin Henney
 
Free Monads Getting Started
Free Monads Getting StartedFree Monads Getting Started
Free Monads Getting StartedKent Ohashi
 
VIM for (PHP) Programmers
VIM for (PHP) ProgrammersVIM for (PHP) Programmers
VIM for (PHP) ProgrammersZendCon
 

Mais procurados (20)

Python
PythonPython
Python
 
Vim Script Programming
Vim Script ProgrammingVim Script Programming
Vim Script Programming
 
Music as data
Music as dataMusic as data
Music as data
 
Ruby 程式語言入門導覽
Ruby 程式語言入門導覽Ruby 程式語言入門導覽
Ruby 程式語言入門導覽
 
Go &lt;-> Ruby
Go &lt;-> RubyGo &lt;-> Ruby
Go &lt;-> Ruby
 
Ruby 程式語言簡介
Ruby 程式語言簡介Ruby 程式語言簡介
Ruby 程式語言簡介
 
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
Haste (Same Language, Multiple Platforms) and Tagless Final Style (Same Synta...
 
Alias
AliasAlias
Alias
 
Template Haskell Tutorial
Template Haskell TutorialTemplate Haskell Tutorial
Template Haskell Tutorial
 
Functional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipperFunctional pe(a)rls: Huey's zipper
Functional pe(a)rls: Huey's zipper
 
Erlang Concurrency
Erlang ConcurrencyErlang Concurrency
Erlang Concurrency
 
A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009A Taste of Python - Devdays Toronto 2009
A Taste of Python - Devdays Toronto 2009
 
Poly-paradigm Java
Poly-paradigm JavaPoly-paradigm Java
Poly-paradigm Java
 
2 BytesC++ course_2014_c2_ flow of control
2 BytesC++ course_2014_c2_ flow of control 2 BytesC++ course_2014_c2_ flow of control
2 BytesC++ course_2014_c2_ flow of control
 
Google Go For Ruby Hackers
Google Go For Ruby HackersGoogle Go For Ruby Hackers
Google Go For Ruby Hackers
 
Vim Hacks
Vim HacksVim Hacks
Vim Hacks
 
Declarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeDeclarative Thinking, Declarative Practice
Declarative Thinking, Declarative Practice
 
Free Monads Getting Started
Free Monads Getting StartedFree Monads Getting Started
Free Monads Getting Started
 
F bound-types
F bound-typesF bound-types
F bound-types
 
VIM for (PHP) Programmers
VIM for (PHP) ProgrammersVIM for (PHP) Programmers
VIM for (PHP) Programmers
 

Semelhante a F# Delight - Getting Started with F# Interactive and Functional Programming Concepts

Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my dayTor Ivry
 
Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsFranco Lombardo
 
Functional Programming in F#
Functional Programming in F#Functional Programming in F#
Functional Programming in F#Dmitri Nesteruk
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional SwiftJason Larsen
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!priort
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and InferenceRichard Fox
 
仕事で使うF#
仕事で使うF#仕事で使うF#
仕事で使うF#bleis tift
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!John De Goes
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsPhilip Schwarz
 
Swift - Modern & Expressive, or Magical Unicorn?
Swift  - Modern & Expressive, or Magical Unicorn?Swift  - Modern & Expressive, or Magical Unicorn?
Swift - Modern & Expressive, or Magical Unicorn?Mike Jones
 
Think sharp, write swift
Think sharp, write swiftThink sharp, write swift
Think sharp, write swiftPascal Batty
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kirill Rozov
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayUtkarsh Sengar
 

Semelhante a F# Delight - Getting Started with F# Interactive and Functional Programming Concepts (20)

Go ahead, make my day
Go ahead, make my dayGo ahead, make my day
Go ahead, make my day
 
Kotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functionsKotlin from-scratch 2 - functions
Kotlin from-scratch 2 - functions
 
Functional Programming in F#
Functional Programming in F#Functional Programming in F#
Functional Programming in F#
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
 
仕事で使うF#
仕事で使うF#仕事で使うF#
仕事で使うF#
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Rustlabs Quick Start
Rustlabs Quick StartRustlabs Quick Start
Rustlabs Quick Start
 
All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!All Aboard The Scala-to-PureScript Express!
All Aboard The Scala-to-PureScript Express!
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
Monoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and CatsMonoids - Part 1 - with examples using Scalaz and Cats
Monoids - Part 1 - with examples using Scalaz and Cats
 
Unfiltered Unveiled
Unfiltered UnveiledUnfiltered Unveiled
Unfiltered Unveiled
 
Intro toswift1
Intro toswift1Intro toswift1
Intro toswift1
 
Swift - Modern & Expressive, or Magical Unicorn?
Swift  - Modern & Expressive, or Magical Unicorn?Swift  - Modern & Expressive, or Magical Unicorn?
Swift - Modern & Expressive, or Magical Unicorn?
 
Think sharp, write swift
Think sharp, write swiftThink sharp, write swift
Think sharp, write swift
 
Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3Kotlin Advanced - Apalon Kotlin Sprint Part 3
Kotlin Advanced - Apalon Kotlin Sprint Part 3
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
 
groovy & grails - lecture 3
groovy & grails - lecture 3groovy & grails - lecture 3
groovy & grails - lecture 3
 
F# intro
F# introF# intro
F# intro
 

Último

Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about usDynamic Netsoft
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Intelisync
 

Último (20)

Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
DNT_Corporate presentation know about us
DNT_Corporate presentation know about usDNT_Corporate presentation know about us
DNT_Corporate presentation know about us
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)Introduction to Decentralized Applications (dApps)
Introduction to Decentralized Applications (dApps)
 

F# Delight - Getting Started with F# Interactive and Functional Programming Concepts

  • 1. August 7, 2017 Tom Prior www.prigrammer.com @priortd F# Delight
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11. Getting started – F# interactive FSI https://www.microsoft.com/net/download/core dotnet new console -lang f# -o MyConsoleApp cd MyConsoleApp dotnet restore code .
  • 12. Create fsx file and start executing code with f# interactive! Just highlight and press Alt-Enter
  • 13. The Delights • Simplicity • Immutability • Pattern matching • Encoding logic in types • Automatic currying – all functions are one arg functions • High level transformations and functional pipelines
  • 14. Immutability – let bindings let x = 2 Evaluated in FSI… val x : int = 2
  • 15. Will this increment x ?? Evaluated in FSI… val x : int = 2 val it : bool = false let x = 2 x = x + 1
  • 16. Specifying Mutability Evaluated in FSI… val mutable y : int = 3 val it : unit = () x <- x + 1 //won’t compile as x not mutable. let mutable y = 2 y <- y + 1
  • 17. Tuples let p = ("Tom", 38) fst p Evaluated in FSI …. val p : string * int = ("Tom", 38) val it : string = "Tom"
  • 18. Immutability – OO Classes type Person(name:string) = member p.Name = name
  • 19. Immutability – Records type Person = { Name : string Age : int } let p = { Name = "Tom"; Age = 56 } Evaluated in FSI… type Person = {Name: string; Age: int;} val p : Person = {Name = "Tom"; Age = 56;}
  • 20. Evaluated in FSI… val it : string = "Tom" //won't compile as records are immutable. p.Name <- "Jack" p.Name
  • 21. Immutable Collections Evaluated in FSI… val numbers : int list = [1; 2; 3; 4] open FSharp.Collections let numbers = [ 1; 2; 3; 4 ] //won't compile becuase lists are immutable numbers.[2] <- 7
  • 22. Arrays still mutable Evaluated in FSI… val names : string [] = [|"tom"; "eleanor"|] val it : string = "tom" let names = [| "tom"; "eleanor" |] names.[0] names.[0] <- "Myles" names.[0] Evaluated in FSI… val it : string = "Myles"
  • 23. Pattern matching Evaluated in FSI… val person : string * int = ("Tom", 38) val name : string = "Tom" val age : int = 38 let person = ("Tom", 38) let (name, age) = person
  • 24. Match expressions Evaluated in FSI… val getName : 'a * 'b -> 'a val person : string * int = ("Tom", 38) val it : string = "Tom" let getName person = match person with | (name, age) -> name let person = ("Tom", 38) getName person
  • 25. Pattern matching on records Evaluated in FSI… type Person = {Name: string; Age: int;} val p : Person = {Name = "Tom"; Age = 38;} val personName : string = "Tom" type Person = { Name : string; Age : int } let p = { Name = "Tom"; Age = 38 } let { Name = personName; Age = _ } = p
  • 26. Pattern matching on lists let l = [ 1; 2; 3 ] 1 2 3 [] //l can be re-written as let l = 1 :: 2 :: 3 :: []
  • 27. Evaluated in FSI… val l : int list = [1; 2; 3] val getFirst : list:'a list -> 'a val it : int = 1 let l = 1 :: 2 :: 3 :: [] let getFirst list = match list with // warning if not all patterns covered | x :: xs -> x | [] -> failwith "cannot get first on an empty list" // you wouldn't actually do this - this would return an option instead - will cover this shortly. getFirst l
  • 28. Discriminated Unions type Drummer = Drummer of string type BassPlayer = BassPlayer of string type SaxPlayer = SaxPlayer of string type PianoPlayer = PianoPlayer of string type JazzBand = | PianoTrio of PianoPlayer * BassPlayer * Drummer | SaxTrio of SaxPlayer * BassPlayer * Drummer | Quartet of SaxPlayer * PianoPlayer * BassPlayer * Drummer
  • 29. Simplified… let getBandLeader (jazzband: JazzBand) = match jazzband with | PianoTrio(PianoPlayer(ppn), BassPlayer(bassPlayerName), Drummer(dn)) -> ppn | SaxTrio(SaxPlayer(spn), BassPlayer(bpn), Drummer(dn)) -> spn | Quartet(SaxPlayer(spn), PianoPlayer(name), BassPlayer(bpn), Drummer(dn)) -> spn let getBandLeader (jazzband: JazzBand) = match jazzband with | PianoTrio(PianoPlayer(pianoPlayerName), _, _) -> pianoPlayerName | SaxTrio(SaxPlayer(saxPlayerName), _, _) -> saxPlayerName | Quartet(SaxPlayer(saxPlayerName), _, _, _) -> saxPlayerName
  • 30. Making illegal states unrepresentable From a different module …. type Drummer = private Drummer of string let createDrummer name = // do some lookup to validate that this person is actually // a drummer let drummers = [ "Max Roache"; "Elvin Jones"; "Tony Williams" ] if List.contains name drummers then Some (Drummer name) else None // won't compile because the union case fields are not accessible let drummer = Drummer("tom")
  • 31. Making illegal states unrepresentable Evaluate in FSI… let drummer = createDrummer "tom" val drummer : Drummer option = None let drummer = createDrummer "Max Roache" Evaluate in FSI… val drummer : Drummer option = Some Drummer "Max Roache"
  • 32. Pattern matching private data constructors let (|Drummer|) (Drummer name) = Drummer(name) let getBandLeader (jazzband: JazzBand) = match jazzband with | PianoTrio(PianoPlayer(ppn), BassPlayer(bassPlayerName), Drummer(dn)) -> ppn | SaxTrio(SaxPlayer(spn), BassPlayer(bpn), Drummer(dn)) -> spn | Quartet(SaxPlayer(spn), PianoPlayer(name), BassPlayer(bpn), Drummer(dn)) -> spn
  • 33. Automatic currying type Message = { Id : Guid Payload : string } let addPrefix (prefix:string, message:Message) = { Id = message.Id Payload = prefix + message.Payload } Evaluate in FSI.. val addPrefix : prefix:string * message:Message -> Message
  • 34. Automatic currying Evaluate in FSI… let message = { Id = Guid.NewGuid(); Payload = "my payload" } let addPrefix' prefix = fun message -> { message with Payload = prefix + message.Payload } addPrefix’ “hello " val it : (Message -> Message) = <fun:it@3> let addHelloPrefix = addPrefix’ “hello " addHelloPrefix message Evaluate in FSI… val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038; Payload = “hello my payload ";}
  • 35. Automatic currying Evaluate in FSI… val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038; Payload = "my prefix to my payload ";} let addHelloPrefix = addPrefix’’ “hello " addHelloPrefix message Evaluate in FSI… val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038; Payload = “hello my payload ";} let addPrefix'' prefix message = { message with Payload = prefix + message.Payload } addPrefix'' "my prefix to " message
  • 36. Functional pipelines Evaluate in FSI… val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038; Payload = “header:my payload:footer ";} let addPostfix postfix message = { message with Payload = message.Payload + postfix } //hard to read with nested parens let transformMessage message = (addPostfix "footer" (addPrefix'' "header:" message)) let transformMessage' message = message |> addPrefix'' "header:" |> addPostfix ":footer" transformMessage' message
  • 37. Functional pipelines Evaluate in FSI… val it : Message = {Id = ac4ddf34-4d9d-4c16-869a-500578f33038; Payload = “header:my payload:footer ";} let addPostfix postfix message = { message with Payload = message.Payload + postfix } //hard to read with nested parens let transformMessage message = (addPostfix "footer" (addPrefix'' "header:" message)) let transformMessage' message = message |> addPrefix'' "header:" |> addPostfix ":footer" transformMessage' message
  • 38. Loops to high level transformations h u z z a h u z z a
  • 39. h u z z u h u z z u z z
  • 40. Imperative C# implementation static bool IsPalindrome(string candidate) { var endIndex = candidate.Length - 1; for(var i = 0; i < candidate.Length/2; i++) { if (candidate[i] != candidate[endIndex - i]) return false; } return true; }
  • 41. Imperative loop in F# let palindromeWithWhileLoop (candidate:string) = let endIndex = candidate.Length - 1 let mutable isPalindrome = true let mutable i = 0 while i < candidate.Length/2 && isPalindrome do if candidate.[i] <> candidate.[endIndex - i] then isPalindrome <- false i <- i + 1 isPalindrome
  • 42. Lets remove the mutable variables let palindromeWithRecursiveLoop (candidate:string) = let endIndex = candidate.Length - 1 let rec loop i isPalindrome = if i < candidate.Length/2 && isPalindrome then loop (i + 1) (candidate.[i] = candidate.[endIndex - i]) else isPalindrome loop 0 true
  • 43. Simplify with pattern matching let rec isPalindrome candidate = let exceptLast list = (list |> List.truncate (list.Length - 1)) match candidate with | [] -> true | [x] -> true | [x1; x2] -> x1 = x2 | x1 :: xs -> x1 = List.last xs && xs |> exceptLast |> isPalindrome
  • 44. Removing the imperative loop let palindromeWithTryFind (candidate: string) = candidate |> Seq.mapi (fun index c -> (index, c)) |> Seq.tryFind (fun (index, c) -> let indexFromEnd = (Seq.length candidate) - (index + 1) indexFromEnd >= index && c <> candidate.[indexFromEnd]) |> Option.isNone
  • 45. Transform only the palindromes let toUppercasePalindromes candidates = candidates |> Seq.filter (fun candidate -> isPalindrome candidate) |> Seq.map (fun palindrome -> palindrome.ToUpper()) Simplified… let toUppercasePalindromes candidates = candidates |> Seq.filter isPalindrome |> Seq.map (fun palindrome -> palindrome.ToUpper()) [ "anina"; "aninaa"; "aniina"; ""; "a"; "at"; "anireina" ] |> toUppercasePalindromes |> Seq.toList Evaluate in FSI… val it : string list = ["ANINA"; "ANIINA"; ""; "A"]
  • 46. Learning Resources https://fsharpforfunandprofit.com/ Kit Eason’s courses on Pluralsight Try hackerrank problems in F# https://www.hackerrank.com/ https://www.pluralsight.com/courses/fsharp-jumpstart