diff --git a/distribution/lib/Standard/Base/0.0.0-dev/src/Function.enso b/distribution/lib/Standard/Base/0.0.0-dev/src/Function.enso index 4a478a005f84b..0ff13aeb343be 100644 --- a/distribution/lib/Standard/Base/0.0.0-dev/src/Function.enso +++ b/distribution/lib/Standard/Base/0.0.0-dev/src/Function.enso @@ -1,3 +1,5 @@ +import Standard.Base + # Function types. type Function @@ -7,3 +9,56 @@ type Function the this argument. @Builtin_Type type Function + + +## An identity function which returns the provided argument. + + Arguments: + - x: the value to return. + + > Example + five = Function.identity 5 # returns number 5 + +Function.identity : a -> a +Function.identity x = x + +## Flips the first two arguments of a function. Returns function that + takes two arguments, but in opposite order. + + Arguments: + - f function that takes two arguments + + > Example + Console.log <| Function.flip (+) "world" "hello" # Prints 'helloworld' + +Function.flip : (a -> b -> c) -> (b -> a -> c) +Function.flip f = (x -> y -> f y x) + + +## Creates a function which drops its input and returns the provided value instead. + The expression const a is the same as \_ -> a. + + Arguments: + - x constant value to return + + > Example + Console.log <| [1, 2, 3].map (Function.const 7) # Prints '[7, 7, 7]' + +Function.const : a -> b -> a +Function.const x _ = x + +## Converts a single-argument function accepting a pair of elements into a multi-argument one. + + Arguments: + - f function accepting pair of values + +Function.curry : ([a, b] -> c) -> (a -> b -> c) +Function.curry f = x -> y -> f [x, y] + +## Converts a multi-argument function into a single-argument one accepting a pair of elements. + + Arguments: + - f function accepting multiple arguments + +Function.uncurry : (a -> b -> c) -> ([a, b] -> c) +Function.uncurry f = (pair -> f pair.head pair.tail.head) diff --git a/engine/polyglot-api/src/main/scala/org/enso/polyglot/PolyglotContext.scala b/engine/polyglot-api/src/main/scala/org/enso/polyglot/PolyglotContext.scala index 32c03297c6ebb..3b738ec0ec8f6 100644 --- a/engine/polyglot-api/src/main/scala/org/enso/polyglot/PolyglotContext.scala +++ b/engine/polyglot-api/src/main/scala/org/enso/polyglot/PolyglotContext.scala @@ -2,6 +2,7 @@ package org.enso.polyglot import java.io.File import org.graalvm.polyglot.{Context, Source} +import java.io.FileOutputStream /** Exposes language specific aliases for generic polyglot context operations. * @param context the Graal polyglot context to use. @@ -15,8 +16,16 @@ class PolyglotContext(val context: Context) { * @return the module representing evaluated code. */ def evalModule(code: String, moduleName: String): Module = { + val f = new File(File.createTempFile("any", ".enso").getParentFile(), moduleName + Integer.toHexString(code.hashCode()) + ".enso") + val os = new FileOutputStream(f) + os.write(code.getBytes()) + os.close() + + System.out.println("Wrote down " + f) + val source = Source - .newBuilder(LanguageInfo.ID, code, moduleName) + .newBuilder(LanguageInfo.ID, f) + .name(moduleName) .build() new Module(context.eval(source)) } diff --git a/test/Tests/src/Data/Function_Spec.enso b/test/Tests/src/Data/Function_Spec.enso new file mode 100644 index 0000000000000..ac2cac4600ba7 --- /dev/null +++ b/test/Tests/src/Data/Function_Spec.enso @@ -0,0 +1,43 @@ +from Standard.Base import all +import Standard.Base.Data.Numbers + +import Standard.Test +from Standard.Base.Data.Ordering import Equal, Less, Greater + +spec = + Test.group "Function.identity" <| + Test.specify "identity on number" <| + (Function.identity 5) . should_equal 5 + + Test.specify "identity on text" <| + (Function.identity '5') . should_equal '5' + + Test.specify "identity on boolean" <| + (Function.identity False) . should_equal False + + Test.group "Function.flip" <| + Test.specify "flip on number" <| + (Function.flip (-) 2 5) . should_equal 3 + + Test.specify "flip on text" <| + (Function.flip (+) "world" "hello") . should_equal "helloworld" + + Test.group "Function.const" <| + Test.specify "const on number" <| + two = Function.const 2 + two 5 . should_equal 2 + + Test.group "Function.curry" <| + Test.specify "curry on number list" <| + sum = x -> x.fold 0 (+) + sum [1, 2, 3, 4] . should_equal 10 + plus = Function.curry sum + plus 6 3 . should_equal 9 + + Test.group "Function.uncurry" <| + Test.specify "uncurry on number list" <| + plus = Function.uncurry (*) + plus [6, 7] . should_equal 42 + + +main = Test.Suite.run_main here.spec diff --git a/test/Tests/src/Main.enso b/test/Tests/src/Main.enso index 8195716994f7c..4d679f6a68d4e 100644 --- a/test/Tests/src/Main.enso +++ b/test/Tests/src/Main.enso @@ -20,6 +20,7 @@ import project.Semantic.R_Interop_Spec import project.Data.Array_Spec import project.Data.Bool_Spec +import project.Data.Function_Spec import project.Data.Interval_Spec import project.Data.Json_Spec import project.Data.List_Spec @@ -65,6 +66,7 @@ main = Test.Suite.run_main <| Any_Spec.spec Array_Spec.spec Bool_Spec.spec + Function_Spec.spec Case_Spec.spec Conversion_Spec.spec Deep_Export_Spec.spec