         fns.reduce($0) { $1($0) }
     }
 }
+
+// Generic version of composeBandTransforms(_:transform2:)
+
+func composeTransforms<T>(transform1: T -> T, transform2: T -> T) -> T -> T {
+    return {
+        transform2(transform1($0))
+    }
+}

print(originalBands)
print(formattedBands(originalBands, [setCanadaAsCountry, capitalizeName]))

// Functional 1

func setCanadaAsCountry(band: Band) -> Band {
    var newBand = band
    newBand["country"] = "Canada"
    return newBand
}

func capitalizeName(band: Band) -> Band {
    var newBand = band
    newBand["name"] = newBand["name"]!.capitalizedString
    return newBand
}

func formatBandsFunctional1(bands: Array<Band>) -> Array<Band> {
    var newBands: Array<Band> = []
    
    for band in bands {
        var newBand = setCanadaAsCountry(band)
        newBand = capitalizeName(newBand)
        
        newBands.append(newBand)
    }
    
    return newBands
}

formatBandsFunctional1(originalBands)

// Functional 2

typealias BandTransformation = Band -> Band

func setCanadaAsCountryTransformation() -> BandTransformation {
    return {
        band in
        
        var newBand = band
        newBand["country"] = "Canada"
        return newBand
    }
}

func capitalizeNameTransformation() -> BandTransformation {
    return {
        band in
        
        var newBand = band
        newBand["name"] = newBand["name"]!.capitalizedString
        return newBand
    }
}

func formatBandsFunctional2(bands: Array<Band>) -> Array<Band> {
    var newBands: Array<Band> = []
    
    for band in bands {
        var newBand = setCanadaAsCountryTransformation()(band)
        newBand = capitalizeNameTransformation()(newBand)
        
        newBands.append(newBand)
    }
    
    return newBands
}

formatBandsFunctional2(originalBands)

// Functional 3

func composeBandTransformations(transformation1: BandTransformation, transformation2: BandTransformation) -> BandTransformation {
    return {
        band in
        
        transformation2(transformation1(band))
    }
}

func formatBandsFunctional3(bands: Array<Band>) -> Array<Band> {
    var newBands: Array<Band> = []
    let myBandTransformation: BandTransformation = composeBandTransformations(setCanadaAsCountryTransformation(), capitalizeNameTransformation())
    
    for band in bands {
        newBands.append(myBandTransformation(band))
    }
    
    return newBands
}


formatBandsFunctional3(originalBands)

// Functional 4

func updatePropertyForBand(band: Band, key: String, update: BandProperty? -> BandProperty?) -> Band {
    var newBand = band
    newBand[key] = update(newBand[key])
    return newBand
}

///////////////////////////////////////////////////////


formatBands(&bands)
print(bands)

// Functional 1

typealias BandProperty = String
typealias Band = Dictionary<String, BandProperty>
typealias BandTransform = Band -> Band
typealias BandPropertyTransform = BandProperty -> BandProperty

func call(fn: BandPropertyTransform, onValueForKey key: String) -> BandTransform {
    return {
        band in
        
