mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34: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)
|
||||
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"
|
||||
|
||||
/*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 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 java.util.Arrays;
|
||||
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);
|
||||
}
|
||||
|
||||
public ArrayValue(List<Value> values) {
|
||||
final int size = values.size();
|
||||
this.elements = values.toArray(new Value[size]);
|
||||
}
|
||||
|
||||
public ArrayValue(ArrayValue array) {
|
||||
this(array.elements);
|
||||
}
|
||||
|
@ -13,7 +13,12 @@ public final class functional implements Module {
|
||||
public void init() {
|
||||
Functions.set("foreach", new functional_foreach());
|
||||
Functions.set("map", new functional_map());
|
||||
Functions.set("flatmap", new functional_flatmap());
|
||||
Functions.set("reduce", new functional_reduce());
|
||||
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;
|
||||
|
||||
import com.annimon.ownlang.exceptions.ArgumentsMismatchException;
|
||||
import com.annimon.ownlang.exceptions.TypeException;
|
||||
import com.annimon.ownlang.lib.*;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public final class functional_map implements Function {
|
||||
public final class functional_combine implements Function {
|
||||
|
||||
@Override
|
||||
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];
|
||||
if (container.type() == Types.ARRAY) {
|
||||
if (args[1].type() != Types.FUNCTION) {
|
||||
throw new RuntimeException("Function expected in second arg");
|
||||
Function result = null;
|
||||
for (Value arg : args) {
|
||||
if (arg.type() != Types.FUNCTION) {
|
||||
throw new TypeException(arg.toString() + " is not a function");
|
||||
}
|
||||
final Function mapper = ((FunctionValue) args[1]).getValue();
|
||||
return mapArray((ArrayValue) container, mapper);
|
||||
final Function current = result;
|
||||
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) {
|
||||
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");
|
||||
return new FunctionValue(result);
|
||||
}
|
||||
|
||||
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