84
Advanced Functional Programming in Industry Jos´ e Pedro Magalh˜ aes November 21, 2014 London, United Kingdom Jos´ e Pedro Magalh˜ aes Advanced Functional Programming in Industry, FP Days 2014 1 / 46

Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

  • Upload
    others

  • View
    18

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Advanced Functional Programming in Industry

Jose Pedro Magalhaes

November 21, 2014London, United Kingdom

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 1 / 46

Page 2: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Introduction

I Haskell: a statically typed, lazy, purely functional language

I Modelling musical harmony using Haskell

I Applications of a model of harmony:I Musical analysisI Finding cover songsI Generating chords and melodiesI Correcting errors in chord extraction from audio sourcesI Chordify—a web-based music player with chord recognition

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 2 / 46

Page 3: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Demo: Chordify

Demo:

http://chordify.net

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 3 / 46

Page 4: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Table of Contents

Harmony

Haskell

Harmony analysis

Harmonic similarity

Music generation

Chord recognition: Chordify

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 4 / 46

Page 5: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

What is harmony?

IVIVI V/V

C F D G7 7 C

{Ton TonSDom Dom

I Harmony arises when at least two notes sound at the same time

I Harmony induces tension and release patterns, that can be describedby music theory and music cognition

I The internal structure of the chord has a large influence on theconsonance or dissonance of a chord

I The surrounding context also has a large influence

Demo: how harmony affects melody

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 5 / 46

Page 6: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

What is harmony?

IVIVI V/V

C F D G7 7 C

{Ton TonSDom Dom

I Harmony arises when at least two notes sound at the same time

I Harmony induces tension and release patterns, that can be describedby music theory and music cognition

I The internal structure of the chord has a large influence on theconsonance or dissonance of a chord

I The surrounding context also has a large influence

Demo: how harmony affects melody

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 5 / 46

Page 7: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Simplified harmony theory I

I A chord is a group of tones separated by intervals of roughly thesame size.

I All music is made out of chords (whether explicitly or not).

I There are 12 different notes. Instead of naming them, we numberthem relative to the first and most important one, the tonic. So weget I, II[, II . . . VI], VII.

I A chord is built on a root note. So I also stands for the chord builton the first degree, V for the chord built on the fifth degree, etc.

I So the following is a chord sequence: I IV II7 V7 I.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 6 / 46

Page 8: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Simplified harmony theory II

Models for musical harmony explain the harmonic progression in music:

I Everything works around the tonic (I).

I The dominant (V) leads to the tonic.

I The subdominant (IV) tends to lead to the dominant.

I Therefore, the I IV V I progression is very common.

I There are also secondary dominants, which lead to a relative tonic.For instance, II7 is the secondary dominant of V, and I7 is thesecondary dominant of IV.

I So you can start with I, add one note to get I7, fall into IV, changetwo notes to get to II7, fall into V, and then finally back to I.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 7 / 46

Page 9: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

An example harmonic analysis

IVIVI V/V

C F D G7 7 C

{Ton TonSDom Dom

Piece

PT

T

I

C

PD

D

D

V/V

V7

G:7

II7

D:7

S

IV

F

PT

T

I

C

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 8 / 46

Page 10: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Why are harmony models useful?

Having a model for musical harmony allows us to automaticallydetermine the functional meaning of chords in the tonal context.The model determines which chords “fit” on a particular moment in asong.

This is useful for:

I Musical information retrieval (find songs similar to a given song)

I Audio and score recognition (improving recognition by knowingwhich chords are more likely to appear)

I Music generation (create sequences of chords that conform to themodel)

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 9 / 46

Page 11: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Why are harmony models useful?

Having a model for musical harmony allows us to automaticallydetermine the functional meaning of chords in the tonal context.The model determines which chords “fit” on a particular moment in asong. This is useful for:

I Musical information retrieval (find songs similar to a given song)

I Audio and score recognition (improving recognition by knowingwhich chords are more likely to appear)

I Music generation (create sequences of chords that conform to themodel)

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 9 / 46

Page 12: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Table of Contents

Harmony

Haskell

Harmony analysis

Harmonic similarity

Music generation

Chord recognition: Chordify

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 10 / 46

Page 13: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Why Haskell?

Haskell is a strongly-typed pure functional programming language:

Strongly-typed All values are classified by their type, and types areknown at compile time (statically). This gives us strongguarantees about our code, avoiding many commonmistakes.

Pure There are no side-effects, so Haskell functions are likemathematical functions.

Functional A Haskell program is an expression, not a sequence ofstatements. Functions are first class citizens, and explicitstate is avoided.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 11 / 46

Page 14: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Notes

data Root = A | B | C | D | E | F | G

type Octave = Int

data Note = Note Root Octave

a4, b4, c4, d4, e4, f4, g4 :: Notea4 = Note A 4b4 = Note B 4c4 = Note C 4d4 = Note D 4e4 = Note E 4f4 = Note F 4g4 = Note G 4

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 12 / 46

Page 15: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Notes

data Root = A | B | C | D | E | F | G

type Octave = Int

data Note = Note Root Octave

a4, b4, c4, d4, e4, f4, g4 :: Notea4 = Note A 4b4 = Note B 4c4 = Note C 4d4 = Note D 4e4 = Note E 4f4 = Note F 4g4 = Note G 4

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 12 / 46

Page 16: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Melody

type Melody = [Note]

cMajScale :: MelodycMajScale = [c4, d4, e4, f4, g4, a4, b4]

cMajScaleRev :: MelodycMajScaleRev = reverse cMajScale

reverse :: [α ]→ [α ]reverse [ ] = [ ]reverse (h : t) = reverse t ++ [h]

(++) :: [α ]→ [α ]→ [α ](++) = . . .

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 13 / 46

Page 17: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Melody

type Melody = [Note]

cMajScale :: MelodycMajScale = [c4, d4, e4, f4, g4, a4, b4]

cMajScaleRev :: MelodycMajScaleRev = reverse cMajScale

reverse :: [α ]→ [α ]reverse [ ] = [ ]reverse (h : t) = reverse t ++ [h]

(++) :: [α ]→ [α ]→ [α ](++) = . . .

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 13 / 46

Page 18: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Melody

type Melody = [Note]

cMajScale :: MelodycMajScale = [c4, d4, e4, f4, g4, a4, b4]

cMajScaleRev :: MelodycMajScaleRev = reverse cMajScale

reverse :: [α ]→ [α ]reverse [ ] = [ ]reverse (h : t) = reverse t ++ [h]

(++) :: [α ]→ [α ]→ [α ](++) = . . .

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 13 / 46

Page 19: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Transposition

Transposing a melody one octave higher:

octaveUp :: Octave→ OctaveoctaveUp n = n + 1

noteOctaveUp :: Note→ NotenoteOctaveUp (Note r o) = Note r (octaveUp o)

melodyOctaveUp :: Melody→ MelodymelodyOctaveUp m = map noteOctaveUp m

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 14 / 46

Page 20: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generation, analysis

Building a canon from a melody:

canon :: Melody→ Melodycanon m = m ++ canon m

Is a given melody in C major?

root :: Note→ Rootroot (Note r o) = r

isCMaj :: Melody→ BoolisCMaj = all (∈ cMajScale) ◦map root

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 15 / 46

Page 21: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generation, analysis

Building a canon from a melody:

canon :: Melody→ Melodycanon m = m ++ canon m

Is a given melody in C major?

root :: Note→ Rootroot (Note r o) = r

isCMaj :: Melody→ BoolisCMaj = all (∈ cMajScale) ◦map root

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 15 / 46

Page 22: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

“Details” left out

We have seen only a glimpse of music representation in Haskell.

I Rhythm

I Accidentals

I Intervals

I Voicing

I . . .

A good pedagogical reference on using Haskell to represent music:http://di.uminho.pt/~jno/html/ipm-1011.html

A serious library for music manipulation:http://www.haskell.org/haskellwiki/Haskore

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 16 / 46

Page 23: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Table of Contents

Harmony

Haskell

Harmony analysis

Harmonic similarity

Music generation

Chord recognition: Chordify

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 17 / 46

Page 24: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Application: harmony analysis

Parsing the sequence Gmin C7 Gmin C7 FMaj D7 G7 CMaj:

Piece

PT

T

I

C:maj

PD

D

D

D

V7

G:7

V/V

II7

D:7

S

IV

F:maj

V/IV

I7

C:7

V/I

Vmin

G:min

S

IV

ins

V/IV

I7

C:7

V/I

Vmin

G:min

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 18 / 46

Page 25: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Table of Contents

Harmony

Haskell

Harmony analysis

Harmonic similarity

Music generation

Chord recognition: Chordify

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 19 / 46

Page 26: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Application: harmonic similarity

I A practical application of a harmony model is to estimate harmonicsimilarity between songs

I The more similar the trees, the more similar the harmony

I We don’t want to write a diff algorithm for our complicated model;we get it automatically by using a generic diff

I The generic diff is a type-safe tree-diff algorithm, part of a student’sMSc work at Utrecht University

I Generic, thus working for any model, and independent of changes tothe model

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 20 / 46

Page 27: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Table of Contents

Harmony

Haskell

Harmony analysis

Harmonic similarity

Music generation

Chord recognition: Chordify

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 21 / 46

Page 28: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Application: automatic harmonisation of melodies

Another practical application of a harmony model is to help selectinggood harmonisations (chord sequences) for a given melody:

!"

" !""IV

!

!"

"""III

!V

# $% $

"

""

"

"""V

"I

"

"""III

"

"""IV

"

"""III

"

"""II

Music engraving by LilyPond 2.16.2—www.lilypond.org

We generate candidate chord sequences, parse them with the harmonymodel, and select the one with the least errors.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 22 / 46

Page 29: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Visualising harmonic structure

Piece

Phrase

Ton

I: Maj

C: Maj

Dom

Dom

V: Dom7

G: Dom7

II: Dom7

D: Dom7

Sub

IV: Maj

F: Maj

III: Min

E: Min

Ton

I: Maj

C: Maj

You can see this tree as having been produced by taking the chords ingreen as input. . .

or the chords might have been dictated by the structure!

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 23 / 46

Page 30: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generating harmonic structure

Piece

Phrase

Ton

I: Maj

C: Maj

Dom

Dom

V: Dom7

G: Dom7

II: Dom7

D: Dom7

Sub

IV: Maj

F: Maj

III: Min

E: Min

Ton

I: Maj

C: Maj

You can see this tree as having been produced by taking the chords ingreen as input. . . or the chords might have been dictated by the structure!

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 23 / 46

Page 31: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

A functional model of harmony

PieceM → [PhraseM] (M ∈ {Maj,Min})

PhraseM → TonM DomM TonM

| DomM TonM

TonMaj → IMaj

TonMin → ImMin

DomM → V7M

| VM

| VII0M| SubM DomM

| II7M V7M

SubMaj → IImMaj

| IVMaj

| IIImMaj IVMaj

SubMin → IVmMin

Simple, but enough for now, and easy to extend.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 24 / 46

Page 32: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

A functional model of harmony

PieceM → [PhraseM] (M ∈ {Maj,Min})

PhraseM → TonM DomM TonM

| DomM TonM

TonMaj → IMaj

TonMin → ImMin

DomM → V7M

| VM

| VII0M| SubM DomM

| II7M V7M

SubMaj → IImMaj

| IVMaj

| IIImMaj IVMaj

SubMin → IVmMin

Simple, but enough for now, and easy to extend.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 24 / 46

Page 33: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

A functional model of harmony

PieceM → [PhraseM] (M ∈ {Maj,Min})

PhraseM → TonM DomM TonM

| DomM TonM

TonMaj → IMaj

TonMin → ImMin

DomM → V7M

| VM

| VII0M| SubM DomM

| II7M V7M

SubMaj → IImMaj

| IVMaj

| IIImMaj IVMaj

SubMin → IVmMin

Simple, but enough for now, and easy to extend.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 24 / 46

Page 34: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

A functional model of harmony

PieceM → [PhraseM] (M ∈ {Maj,Min})

PhraseM → TonM DomM TonM

| DomM TonM

TonMaj → IMaj

TonMin → ImMin

DomM → V7M

| VM

| VII0M| SubM DomM

| II7M V7M

SubMaj → IImMaj

| IVMaj

| IIImMaj IVMaj

SubMin → IVmMin

Simple, but enough for now, and easy to extend.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 24 / 46

Page 35: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

A functional model of harmony

PieceM → [PhraseM] (M ∈ {Maj,Min})

PhraseM → TonM DomM TonM

| DomM TonM

TonMaj → IMaj

TonMin → ImMin

DomM → V7M

| VM

| VII0M| SubM DomM

| II7M V7M

SubMaj → IImMaj

| IVMaj

| IIImMaj IVMaj

SubMin → IVmMin

Simple, but enough for now, and easy to extend.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 24 / 46

Page 36: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

A functional model of harmony

PieceM → [PhraseM] (M ∈ {Maj,Min})

PhraseM → TonM DomM TonM

| DomM TonM

TonMaj → IMaj

TonMin → ImMin

DomM → V7M

| VM

| VII0M| SubM DomM

| II7M V7M

SubMaj → IImMaj

| IVMaj

| IIImMaj IVMaj

SubMin → IVmMin

Simple, but enough for now, and easy to extend.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 24 / 46

Page 37: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—IA naive datatype encoding musical harmony:

data Piece = Piece [ Phrase ]

data Phrase wherePhraseIVI :: Ton→ Dom→ Ton→ PhrasePhraseVI :: Dom→ Ton→ Phrase

data Ton whereTonMaj :: Degree→ TonTonMin :: Degree→ Ton

data Dom whereDomV7 :: Degree→ DomDomV :: Degree→ DomDomVII0 :: Degree→ DomDomIV−V :: SDom→ Dom→ DomDomII−V :: Degree→ Degree→ Dom

data Degree = I | II | III . . .

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 25 / 46

Page 38: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—IA naive datatype encoding musical harmony:

data Piece = Piece [ Phrase ]

data Phrase wherePhraseIVI :: Ton→ Dom→ Ton→ PhrasePhraseVI :: Dom→ Ton→ Phrase

data Ton whereTonMaj :: Degree→ TonTonMin :: Degree→ Ton

data Dom whereDomV7 :: Degree→ DomDomV :: Degree→ DomDomVII0 :: Degree→ DomDomIV−V :: SDom→ Dom→ DomDomII−V :: Degree→ Degree→ Dom

data Degree = I | II | III . . .

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 25 / 46

Page 39: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—IA naive datatype encoding musical harmony:

data Piece = Piece [ Phrase ]

data Phrase wherePhraseIVI :: Ton→ Dom→ Ton→ PhrasePhraseVI :: Dom→ Ton→ Phrase

data Ton whereTonMaj :: Degree→ TonTonMin :: Degree→ Ton

data Dom whereDomV7 :: Degree→ DomDomV :: Degree→ DomDomVII0 :: Degree→ DomDomIV−V :: SDom→ Dom→ DomDomII−V :: Degree→ Degree→ Dom

data Degree = I | II | III . . .

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 25 / 46

Page 40: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—IA naive datatype encoding musical harmony:

data Piece = Piece [ Phrase ]

data Phrase wherePhraseIVI :: Ton→ Dom→ Ton→ PhrasePhraseVI :: Dom→ Ton→ Phrase

data Ton whereTonMaj :: Degree→ TonTonMin :: Degree→ Ton

data Dom whereDomV7 :: Degree→ DomDomV :: Degree→ DomDomVII0 :: Degree→ DomDomIV−V :: SDom→ Dom→ DomDomII−V :: Degree→ Degree→ Dom

data Degree = I | II | III . . .

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 25 / 46

Page 41: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—IIA GADT encoding musical harmony:

data Mode = MajMode | MinMode

data Piece (µ :: Mode) wherePiece :: [ Phrase µ ]→ Piece µ

data Phrase (µ :: Mode) wherePhraseIVI :: Ton µ→ Dom µ→ Ton µ→ Phrase µPhraseVI :: Dom µ→ Ton µ→ Phrase µ

data Ton (µ :: Mode) whereTonMaj :: SD I Maj→ Ton MajMode

TonMin :: SD I Min→ Ton MinMode

data Dom (µ :: Mode) whereDomV7 :: SD V Dom7 → Dom µDomV :: SD V Maj → Dom µDomVII0 :: SD VII Dim → Dom µDomIV−V :: SDom µ→ Dom µ→ Dom µDomII−V :: SD II Dom7 → SD V Dom7 → Dom µ

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 26 / 46

Page 42: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—IIA GADT encoding musical harmony:

data Mode = MajMode | MinMode

data Piece (µ :: Mode) wherePiece :: [ Phrase µ ]→ Piece µ

data Phrase (µ :: Mode) wherePhraseIVI :: Ton µ→ Dom µ→ Ton µ→ Phrase µPhraseVI :: Dom µ→ Ton µ→ Phrase µ

data Ton (µ :: Mode) whereTonMaj :: SD I Maj→ Ton MajMode

TonMin :: SD I Min→ Ton MinMode

data Dom (µ :: Mode) whereDomV7 :: SD V Dom7 → Dom µDomV :: SD V Maj → Dom µDomVII0 :: SD VII Dim → Dom µDomIV−V :: SDom µ→ Dom µ→ Dom µDomII−V :: SD II Dom7 → SD V Dom7 → Dom µ

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 26 / 46

Page 43: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—IIA GADT encoding musical harmony:

data Mode = MajMode | MinMode

data Piece (µ :: Mode) wherePiece :: [ Phrase µ ]→ Piece µ

data Phrase (µ :: Mode) wherePhraseIVI :: Ton µ→ Dom µ→ Ton µ→ Phrase µPhraseVI :: Dom µ→ Ton µ→ Phrase µ

data Ton (µ :: Mode) whereTonMaj :: SD I Maj→ Ton MajMode

TonMin :: SD I Min→ Ton MinMode

data Dom (µ :: Mode) whereDomV7 :: SD V Dom7 → Dom µDomV :: SD V Maj → Dom µDomVII0 :: SD VII Dim → Dom µDomIV−V :: SDom µ→ Dom µ→ Dom µDomII−V :: SD II Dom7 → SD V Dom7 → Dom µ

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 26 / 46

Page 44: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—IIA GADT encoding musical harmony:

data Mode = MajMode | MinMode

data Piece (µ :: Mode) wherePiece :: [ Phrase µ ]→ Piece µ

data Phrase (µ :: Mode) wherePhraseIVI :: Ton µ→ Dom µ→ Ton µ→ Phrase µPhraseVI :: Dom µ→ Ton µ→ Phrase µ

data Ton (µ :: Mode) whereTonMaj :: SD I Maj→ Ton MajMode

TonMin :: SD I Min→ Ton MinMode

data Dom (µ :: Mode) whereDomV7 :: SD V Dom7 → Dom µDomV :: SD V Maj → Dom µDomVII0 :: SD VII Dim → Dom µDomIV−V :: SDom µ→ Dom µ→ Dom µDomII−V :: SD II Dom7 → SD V Dom7 → Dom µ

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 26 / 46

Page 45: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—III

Scale degrees are the leaves of our hierarchical structure:

data DiatonicDegree = I | II | III | IV | V | VI | VIIdata Quality = Maj | Min | Dom7 | Dim

data SD (δ :: DiatonicDegree) (γ :: Quality) whereSurfaceChord :: ChordDegree→ SD δ γ

Now everything is properly indexed, and our GADT is effectivelyconstrained to allow only “harmonically valid” sequences!

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 27 / 46

Page 46: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Now in Haskell—III

Scale degrees are the leaves of our hierarchical structure:

data DiatonicDegree = I | II | III | IV | V | VI | VIIdata Quality = Maj | Min | Dom7 | Dim

data SD (δ :: DiatonicDegree) (γ :: Quality) whereSurfaceChord :: ChordDegree→ SD δ γ

Now everything is properly indexed, and our GADT is effectivelyconstrained to allow only “harmonically valid” sequences!

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 27 / 46

Page 47: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generating harmony

Now that we have a datatype representing harmony sequences, how dowe generate a sequence of chords?

QuickCheck! We give Arbitrary instances for each of the datatypes in ourmodel.

. . . but we don’t want to do this by hand, for every datatype, and to haveto adapt the instances every time we change the model. . . so we usegeneric programming:

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 28 / 46

Page 48: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generating harmony

Now that we have a datatype representing harmony sequences, how dowe generate a sequence of chords?

QuickCheck! We give Arbitrary instances for each of the datatypes in ourmodel.

. . . but we don’t want to do this by hand, for every datatype, and to haveto adapt the instances every time we change the model. . . so we usegeneric programming:

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 28 / 46

Page 49: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generating harmony

Now that we have a datatype representing harmony sequences, how dowe generate a sequence of chords?

QuickCheck! We give Arbitrary instances for each of the datatypes in ourmodel.

. . . but we don’t want to do this by hand, for every datatype, and to haveto adapt the instances every time we change the model. . . so we usegeneric programming:

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 28 / 46

Page 50: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generating harmony

Now that we have a datatype representing harmony sequences, how dowe generate a sequence of chords?

QuickCheck! We give Arbitrary instances for each of the datatypes in ourmodel.

. . . but we don’t want to do this by hand, for every datatype, and to haveto adapt the instances every time we change the model. . . so we usegeneric programming:

gen :: ∀α.(Representable α,Generate (Rep α))⇒ Gen α

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 28 / 46

Page 51: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generating harmony

Now that we have a datatype representing harmony sequences, how dowe generate a sequence of chords?

QuickCheck! We give Arbitrary instances for each of the datatypes in ourmodel.

. . . but we don’t want to do this by hand, for every datatype, and to haveto adapt the instances every time we change the model. . . so we usegeneric programming:

gen :: ∀α.(Representable α,Generate (Rep α))⇒ [ (String,Int) ]→ Gen α

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 28 / 46

Page 52: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Examples of harmony generation

testGen :: Gen (Phrase MajMode)testGen = gen [("Dom_IV-V", 3), ("Dom_II-V", 4)]

example :: IO ()example = let k = Key (Note \ C) MajMode

in sample′ testGen>>= mapM (printOnKey k)

> example[C: Maj,D: Dom7,G: Dom7,C: Maj][C: Maj,G: Dom7,C: Maj][C: Maj,E: Min,F: Maj,G: Maj,C: Maj][C: Maj,E: Min,F: Maj,D: Dom7,G: Dom7,C: Maj][C: Maj,D: Min,E: Min,F: Maj,D: Dom7,G: Dom7,C: Maj]

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 29 / 46

Page 53: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Examples of harmony generation

testGen :: Gen (Phrase MajMode)testGen = gen [("Dom_IV-V", 3), ("Dom_II-V", 4)]

example :: IO ()example = let k = Key (Note \ C) MajMode

in sample′ testGen>>= mapM (printOnKey k)

> example[C: Maj,D: Dom7,G: Dom7,C: Maj][C: Maj,G: Dom7,C: Maj][C: Maj,E: Min,F: Maj,G: Maj,C: Maj][C: Maj,E: Min,F: Maj,D: Dom7,G: Dom7,C: Maj][C: Maj,D: Min,E: Min,F: Maj,D: Dom7,G: Dom7,C: Maj]

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 29 / 46

Page 54: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generating a melody for a given harmony

We then generate a melody in 4 steps:

1. Generate a list of candidate melody notes per chord;

2. Refine the candidates by filtering out obviously bad candidates;

3. Pick one focal candidate melody note per chord;

4. Embellish the candidate notes to produce a final melody.

These four steps combine naturally using plain monadic bind:

melody :: Key→ State MyState Songmelody k = genCandidates>>= refine>>= pickOne>>= embellish

>>= return ◦ Song k

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 30 / 46

Page 55: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Generating a melody for a given harmony

We then generate a melody in 4 steps:

1. Generate a list of candidate melody notes per chord;

2. Refine the candidates by filtering out obviously bad candidates;

3. Pick one focal candidate melody note per chord;

4. Embellish the candidate notes to produce a final melody.

These four steps combine naturally using plain monadic bind:

melody :: Key→ State MyState Songmelody k = genCandidates>>= refine>>= pickOne>>= embellish

>>= return ◦ Song k

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 30 / 46

Page 56: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Example I

&

?

œ œ œ œ œ œ œ œ œœ œ œ œ œ œ œ œ œ œ œ

œœœ

œœœ

œœœ

œœœœ#

œœœœ

n

œœœ

Phrase

Ton

I: Maj

C: Maj

Dom

Dom

V: Dom7

G: Dom7

II: Dom7

D: Dom7

Sub

IV: Maj

F: Maj

III: Min

E: Min

Ton

I: Maj

C: Maj

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 31 / 46

Page 57: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Example II

&

#

?#

œ œ œ œ œ œ œ œ œ œ œ œ œ

œœœ

œœœ

œœœ

œœœœ##

œœœœ

n

#œœœ

Phrase

Ton

I: Min

E: Min

Dom

Dom

Dom

V: Dom7

B: Dom7

II: Dom7

F]: Dom7

Sub

IV: Min

A: Min

Sub

IV: Min

A: Min

Ton

I: Min

E: Min

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 32 / 46

Page 58: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Table of Contents

Harmony

Haskell

Harmony analysis

Harmonic similarity

Music generation

Chord recognition: Chordify

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 33 / 46

Page 59: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Back to Chordify: chord recognition

Yet another practical application of a harmony model is to improve chordrecognition from audio sources.

0.92 C 0.96 EmChord candidates 0.94 Gm 0.97 C

1.00 C 1.00 G 1.00 EmBeat number 1 2 3

How to pick the right chord from the chord candidate list? Ask theharmony model which one fits best.

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 34 / 46

Page 60: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Chordify: architecture

I FrontendI Reads user input, such as YouTube/Soundcloud/Deezer links, or filesI Extracts audioI Calls the backend to obtain the chords for the audioI Displays the result to the userI Implements a queueing system, and library functionalityI Uses PHP, JavaScript, MongoDB

I BackendI Takes an audio file as input, analyses it, extracts the chordsI The chord extraction code uses GADTs, type families, generic

programming (see the HarmTrace package on Hackage)I Performs PDF and MIDI export (using LilyPond)I Uses Haskell, SoX, sonic annotator, and is mostly open source

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 35 / 46

Page 61: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Chordify: architecture

I FrontendI Reads user input, such as YouTube/Soundcloud/Deezer links, or filesI Extracts audioI Calls the backend to obtain the chords for the audioI Displays the result to the userI Implements a queueing system, and library functionalityI Uses PHP, JavaScript, MongoDB

I BackendI Takes an audio file as input, analyses it, extracts the chordsI The chord extraction code uses GADTs, type families, generic

programming (see the HarmTrace package on Hackage)I Performs PDF and MIDI export (using LilyPond)I Uses Haskell, SoX, sonic annotator, and is mostly open source

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 35 / 46

Page 62: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Chordify: numbers

I Online since January 2013

I Top countries: US, UK, Germany, Indonesia, Canada

I Views: 3M+ (monthly)

I Chordified songs: 1.5M+

I Registered users: 200K

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 36 / 46

Page 63: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

How do we handle these visitors?

I Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB harddrive

I Single server hosts both the web and database servers

I Can easily handle peaks of (at least) 700 visitors at a time

I Chordifying new songs takes some computing power, but most songsare in the database already

I Queueing system for busy periods

I Infrastructure costs are minimal

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 37 / 46

Page 64: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

How do we handle these visitors?

I Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB harddrive

I Single server hosts both the web and database servers

I Can easily handle peaks of (at least) 700 visitors at a time

I Chordifying new songs takes some computing power, but most songsare in the database already

I Queueing system for busy periods

I Infrastructure costs are minimal

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 37 / 46

Page 65: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

How do we handle these visitors?

I Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB harddrive

I Single server hosts both the web and database servers

I Can easily handle peaks of (at least) 700 visitors at a time

I Chordifying new songs takes some computing power, but most songsare in the database already

I Queueing system for busy periods

I Infrastructure costs are minimal

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 37 / 46

Page 66: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

How do we handle these visitors?

I Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB harddrive

I Single server hosts both the web and database servers

I Can easily handle peaks of (at least) 700 visitors at a time

I Chordifying new songs takes some computing power, but most songsare in the database already

I Queueing system for busy periods

I Infrastructure costs are minimal

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 37 / 46

Page 67: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

How do we handle these visitors?

I Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB harddrive

I Single server hosts both the web and database servers

I Can easily handle peaks of (at least) 700 visitors at a time

I Chordifying new songs takes some computing power, but most songsare in the database already

I Queueing system for busy periods

I Infrastructure costs are minimal

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 37 / 46

Page 68: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

How do we handle these visitors?

I Single VPS, 6 Intel Xeon cores, 24GB RAM, 500GB SSD, 2TB harddrive

I Single server hosts both the web and database servers

I Can easily handle peaks of (at least) 700 visitors at a time

I Chordifying new songs takes some computing power, but most songsare in the database already

I Queueing system for busy periods

I Infrastructure costs are minimal

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 37 / 46

Page 69: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Frontend (PHP/JS) and backend (Haskell) interaction

I Frontend receives a music file, calls backend with it

I Backend computes the chords, writes them to a file:

I 1;D:min;0.232199546;0.615328798

2;D:min;0.615328798;0.998458049

...

I Frontend reads this file, updates the database if necessary, andrenders the result

I Backend is open-source (and GPL3); only option is to run it as astandalone executable

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 38 / 46

Page 70: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Frontend (PHP/JS) and backend (Haskell) interaction

I Frontend receives a music file, calls backend with it

I Backend computes the chords, writes them to a file:

I 1;D:min;0.232199546;0.615328798

2;D:min;0.615328798;0.998458049

...

I Frontend reads this file, updates the database if necessary, andrenders the result

I Backend is open-source (and GPL3); only option is to run it as astandalone executable

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 38 / 46

Page 71: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Frontend (PHP/JS) and backend (Haskell) interaction

I Frontend receives a music file, calls backend with it

I Backend computes the chords, writes them to a file:I 1;D:min;0.232199546;0.615328798

2;D:min;0.615328798;0.998458049

...

I Frontend reads this file, updates the database if necessary, andrenders the result

I Backend is open-source (and GPL3); only option is to run it as astandalone executable

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 38 / 46

Page 72: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Frontend (PHP/JS) and backend (Haskell) interaction

I Frontend receives a music file, calls backend with it

I Backend computes the chords, writes them to a file:I 1;D:min;0.232199546;0.615328798

2;D:min;0.615328798;0.998458049

...

I Frontend reads this file, updates the database if necessary, andrenders the result

I Backend is open-source (and GPL3); only option is to run it as astandalone executable

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 38 / 46

Page 73: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Frontend (PHP/JS) and backend (Haskell) interaction

I Frontend receives a music file, calls backend with it

I Backend computes the chords, writes them to a file:I 1;D:min;0.232199546;0.615328798

2;D:min;0.615328798;0.998458049

...

I Frontend reads this file, updates the database if necessary, andrenders the result

I Backend is open-source (and GPL3); only option is to run it as astandalone executable

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 38 / 46

Page 74: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

The importance of the UI

Let’s have a look at four different online services giving you the chordsfor a song (Radiohead’s Karma Police).

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 39 / 46

Page 75: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

The importance of the UI—Chordie

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 40 / 46

Page 76: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

The importance of the UI—Riffstation

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 41 / 46

Page 77: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

The importance of the UI—Youtab.me

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 42 / 46

Page 78: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

The importance of the UI—Chordify

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 43 / 46

Page 79: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Logistics of an internet start-up

I Chordify is created and funded by 5 people

I If you can do without venture capital, do it!

I You might end up doing more than just functional programming,though:

I Deciding on what features to implement nextI Recruiting, interviewing, dealing with legal issues related to

employmentI Taxation (complicated by the fact that we sell worldwide and support

multiple currencies)I User supportI Outreach (pitching events, media, this talk, etc.)

I But it’s fun, and you learn a lot!

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 44 / 46

Page 80: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Logistics of an internet start-up

I Chordify is created and funded by 5 people

I If you can do without venture capital, do it!

I You might end up doing more than just functional programming,though:

I Deciding on what features to implement nextI Recruiting, interviewing, dealing with legal issues related to

employmentI Taxation (complicated by the fact that we sell worldwide and support

multiple currencies)I User supportI Outreach (pitching events, media, this talk, etc.)

I But it’s fun, and you learn a lot!

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 44 / 46

Page 81: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Logistics of an internet start-up

I Chordify is created and funded by 5 people

I If you can do without venture capital, do it!

I You might end up doing more than just functional programming,though:

I Deciding on what features to implement nextI Recruiting, interviewing, dealing with legal issues related to

employmentI Taxation (complicated by the fact that we sell worldwide and support

multiple currencies)I User supportI Outreach (pitching events, media, this talk, etc.)

I But it’s fun, and you learn a lot!

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 44 / 46

Page 82: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Logistics of an internet start-up

I Chordify is created and funded by 5 people

I If you can do without venture capital, do it!

I You might end up doing more than just functional programming,though:

I Deciding on what features to implement nextI Recruiting, interviewing, dealing with legal issues related to

employmentI Taxation (complicated by the fact that we sell worldwide and support

multiple currencies)I User supportI Outreach (pitching events, media, this talk, etc.)

I But it’s fun, and you learn a lot!

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 44 / 46

Page 83: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Summary

Musical modelling with Haskell:

I A model for musical harmony as a Haskell datatype

I Makes use of several advanced functional programming techniques,such as generic programming, GADTs, and type families

I When chords do not fit the model: error correction

I Harmonising melodies

I Generating harmonies

I Recognising harmony from audio sources

I Transporting academic research into industry

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 45 / 46

Page 84: Advanced Functional Programming in Industrydreixel.net/research/pdf/afpi_pres_fpdays14.pdf · Introduction I Haskell: a statically typed, lazy, purely functional language I Modelling

Play with it!

http://chordify.net

http://hackage.haskell.org/package/HarmTrace

http://hackage.haskell.org/package/FComp

Jose Pedro Magalhaes Advanced Functional Programming in Industry, FP Days 2014 46 / 46