mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 08:44:20 +03:00
Добавлено комбинирование функий и flatmap
This commit is contained in:
parent
47dfae5740
commit
02fe4b6e0c
14
program.own
14
program.own
@ -126,6 +126,11 @@ squares = map(nums, def(x) = x * x)
|
|||||||
foreach(squares, ::echo)
|
foreach(squares, ::echo)
|
||||||
println "Sum: " + reduce(squares, 0, def(x, y) = x + y)
|
println "Sum: " + reduce(squares, 0, def(x, y) = x + y)
|
||||||
|
|
||||||
|
nums = [[1, 2], [3], [], [4, 5]]
|
||||||
|
nums = flatmap(nums, IDENTITY)
|
||||||
|
println "flatmap"
|
||||||
|
foreach(nums, ::echo)
|
||||||
|
|
||||||
use "http"
|
use "http"
|
||||||
|
|
||||||
/*http("http://jsonplaceholder.typicode.com/users", "POST", {"name": "OwnLang", "versionCode": 10}, def(v) {
|
/*http("http://jsonplaceholder.typicode.com/users", "POST", {"name": "OwnLang", "versionCode": 10}, def(v) {
|
||||||
@ -165,3 +170,12 @@ def fact2(n) = match n {
|
|||||||
|
|
||||||
println fact1(6)
|
println fact1(6)
|
||||||
println fact2(6)
|
println fact2(6)
|
||||||
|
|
||||||
|
class = {
|
||||||
|
"add": def(a, b) = a + b,
|
||||||
|
"sub": def(a, b) = a - b,
|
||||||
|
"mul": def(a, b) = a * b,
|
||||||
|
"div": def(a, b) = a / b
|
||||||
|
}
|
||||||
|
|
||||||
|
println class.add(2, class.mul(2, 2))
|
@ -3,6 +3,7 @@ package com.annimon.ownlang.lib;
|
|||||||
import com.annimon.ownlang.exceptions.TypeException;
|
import com.annimon.ownlang.exceptions.TypeException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -39,6 +40,11 @@ public final class ArrayValue implements Value, Iterable<Value> {
|
|||||||
System.arraycopy(elements, 0, this.elements, 0, elements.length);
|
System.arraycopy(elements, 0, this.elements, 0, elements.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayValue(List<Value> values) {
|
||||||
|
final int size = values.size();
|
||||||
|
this.elements = values.toArray(new Value[size]);
|
||||||
|
}
|
||||||
|
|
||||||
public ArrayValue(ArrayValue array) {
|
public ArrayValue(ArrayValue array) {
|
||||||
this(array.elements);
|
this(array.elements);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,12 @@ public final class functional implements Module {
|
|||||||
public void init() {
|
public void init() {
|
||||||
Functions.set("foreach", new functional_foreach());
|
Functions.set("foreach", new functional_foreach());
|
||||||
Functions.set("map", new functional_map());
|
Functions.set("map", new functional_map());
|
||||||
|
Functions.set("flatmap", new functional_flatmap());
|
||||||
Functions.set("reduce", new functional_reduce());
|
Functions.set("reduce", new functional_reduce());
|
||||||
Functions.set("filter", new functional_filter());
|
Functions.set("filter", new functional_filter());
|
||||||
|
|
||||||
|
Functions.set("combine", new functional_combine());
|
||||||
|
|
||||||
|
Variables.set("IDENTITY", new FunctionValue(args -> args[0]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,55 +1,29 @@
|
|||||||
package com.annimon.ownlang.lib.modules.functions;
|
package com.annimon.ownlang.lib.modules.functions;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
|
||||||
|
import com.annimon.ownlang.exceptions.TypeException;
|
||||||
import com.annimon.ownlang.lib.*;
|
import com.annimon.ownlang.lib.*;
|
||||||
|
|
||||||
import java.util.Map;
|
public final class functional_combine implements Function {
|
||||||
|
|
||||||
public final class functional_map implements Function {
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Value execute(Value... args) {
|
public Value execute(Value... args) {
|
||||||
if (args.length < 2) throw new RuntimeException("At least two args expected");
|
if (args.length < 1) throw new ArgumentsMismatchException("At least one arg expected");
|
||||||
|
|
||||||
final Value container = args[0];
|
Function result = null;
|
||||||
if (container.type() == Types.ARRAY) {
|
for (Value arg : args) {
|
||||||
if (args[1].type() != Types.FUNCTION) {
|
if (arg.type() != Types.FUNCTION) {
|
||||||
throw new RuntimeException("Function expected in second arg");
|
throw new TypeException(arg.toString() + " is not a function");
|
||||||
}
|
}
|
||||||
final Function mapper = ((FunctionValue) args[1]).getValue();
|
final Function current = result;
|
||||||
return mapArray((ArrayValue) container, mapper);
|
final Function next = ((FunctionValue) arg).getValue();
|
||||||
|
result = fArgs -> {
|
||||||
|
if (current == null) return next.execute(fArgs);
|
||||||
|
return next.execute(current.execute(fArgs));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container.type() == Types.MAP) {
|
return new FunctionValue(result);
|
||||||
if (args[1].type() != Types.FUNCTION) {
|
|
||||||
throw new RuntimeException("Function expected in second arg");
|
|
||||||
}
|
|
||||||
if (args[2].type() != Types.FUNCTION) {
|
|
||||||
throw new RuntimeException("Function expected in third arg");
|
|
||||||
}
|
|
||||||
final Function keyMapper = ((FunctionValue) args[1]).getValue();
|
|
||||||
final Function valueMapper = ((FunctionValue) args[2]).getValue();
|
|
||||||
return mapMap((MapValue) container, keyMapper, valueMapper);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new RuntimeException("Invalid first argument. Array or map exprected");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Value mapArray(ArrayValue array, Function mapper) {
|
|
||||||
final int size = array.size();
|
|
||||||
final ArrayValue result = new ArrayValue(size);
|
|
||||||
for (int i = 0; i < size; i++) {
|
|
||||||
result.set(i, mapper.execute(array.get(i)));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Value mapMap(MapValue map, Function keyMapper, Function valueMapper) {
|
|
||||||
final MapValue result = new MapValue(map.size());
|
|
||||||
for (Map.Entry<Value, Value> element : map) {
|
|
||||||
final Value newKey = keyMapper.execute(element.getKey());
|
|
||||||
final Value newValue = valueMapper.execute(element.getValue());
|
|
||||||
result.set(newKey, newValue);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.annimon.ownlang.lib.modules.functions;
|
||||||
|
|
||||||
|
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
|
||||||
|
import com.annimon.ownlang.exceptions.TypeException;
|
||||||
|
import com.annimon.ownlang.lib.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class functional_flatmap implements Function {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Value execute(Value... args) {
|
||||||
|
if (args.length < 2) throw new ArgumentsMismatchException("At least two arguments expected");
|
||||||
|
|
||||||
|
if (args[0].type() != Types.ARRAY) {
|
||||||
|
throw new TypeException("Array expected in first argument");
|
||||||
|
}
|
||||||
|
if (args[1].type() != Types.FUNCTION) {
|
||||||
|
throw new TypeException("Function expected in second argument");
|
||||||
|
}
|
||||||
|
|
||||||
|
final Function mapper = ((FunctionValue) args[1]).getValue();
|
||||||
|
return flatMapArray((ArrayValue) args[0], mapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value flatMapArray(ArrayValue array, Function mapper) {
|
||||||
|
final List<Value> values = new ArrayList<>();
|
||||||
|
final int size = array.size();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
final Value inner = mapper.execute(array.get(i));
|
||||||
|
if (inner.type() != Types.ARRAY) {
|
||||||
|
throw new TypeException("Array expected " + inner);
|
||||||
|
}
|
||||||
|
for (Value value : (ArrayValue) inner) {
|
||||||
|
values.add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new ArrayValue(values);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user