map, filter and reduce programming by composition

22
Map, filter and reduce Programming by composition

Post on 19-Dec-2015

232 views

Category:

Documents


1 download

TRANSCRIPT

Map, filter and reduce

Programming by composition

Mapping

• Apply operation to each element of a list, gathering the results in a new list.

• Example:– list: (“Your” “call” “is” “important” “to” “us”)– operation: string length– result: (4 4 2 9 2 2)

Conceptual diagram(specific case)

(“Your” “call” “is” “important” “to” “us”)

MAPString length

(4 4 2 9 2 2)

Conceptual diagram(generalized)

Input list

MAPUnary

Operation

Output list

Conceptual diagram(generalized)

Input list

MAPUnary

Operation

Output list

INVARIANT

VARIANTSVARIANTS

Conceptual diagram(generalized)

Input list

MAPUnary

Operation

Output list

public class Map<Domain, Range> implements IAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> {

public LRStruct<Range> emptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); }

public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); }}

Code (Map)

public class Map<Domain, Range> implements IAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> {

public LRStruct<Range> emptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); }

public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); }}

Code (Map)Invariant parts

public class Map<Domain, Range> implements IAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> {

public LRStruct<Range> emptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); }

public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); }}

Code (Map)Invariant parts

public class Map<Domain, Range> implements IAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> {

public LRStruct<Range> emptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); }

public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); }}

Map operation to rest of list, getting answer recursively

Code (Map)Invariant parts

public class Map<Domain, Range> implements IAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> {

public LRStruct<Range> emptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); }

public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); }}

Apply operation to first item of list

Code (Map)Invariant parts

public class Map<Domain, Range> implements IAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> {

public LRStruct<Range> emptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); }

public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); }}

Insert result intonew list

Code (Map)Invariant parts

public class Map<Domain, Range> implements IAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> {

public LRStruct<Range> emptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); }

public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); }}

Code (Map)Variant parts

VARIANT: the input listVARIANT: the input list

public class Map<Domain, Range> implements IAlgo<IUnaryOperation<Domain,Range>,Domain,LRStruct<Range>> {

public LRStruct<Range> emptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return new LRStruct<Range>(); }

public LRStruct<Range> nonEmptyCase(LRStruct<Domain> host,

IUnaryOperation<Domain,Range> arg) { return host.getRest().execute(this,arg).insertFront(arg.apply(host.getDatum())); }}

VARIANT: the operation

Code (Map)Variant parts

VARIANT: the operation

The IUnaryOperation interfacepublic interface IUnaryOperation<Domain, Range> {

public Range apply(Domain arg);}

Mapping: Domain Rangef: x f(x)

DOMAIN RANGE

x

f(x)

A concrete operationpublic class StringLen implements IUnaryOperation<String,Integer>{

public Integer apply(String arg) {return arg.length();

}} DOMAIN

RANGE

A concrete operationpublic class Times2 implements IUnaryOperation<Integer,Integer> {

public Integer apply(Integer arg) {return 2*arg;

}

public String toString() {return "x -> 2*x";

}}

DOMAIN

RANGE

Reduction

• Combine all values of a list using (op,id) a binary operation op, with identity element id.

• Example:– list: (4 4 2 9 2 2)– operation (+,0)– result: 23

The IBinaryOperation interfacepublic interface IBinaryOperation<Domain1,Domain2,Range> {

public Range apply(Domain1 arg1, Domain2 arg2);public Range identityElement();

}

Filtering

• Apply a predicate to each element of a list, building a new list of those elements for which the predicate is true.

• Example:– list: (“Your” “call” “is” “important” “to” “us”)– predicate: contains exactly one vowel– result: (“call” “is” “to” “us”)

The IPredicate interfacepublic interface IBinaryOperation<Domain1,Domain2,Range> {

public Range apply(Domain1 arg1, Domain2 arg2);public Range identityElement();

}