Implementing basic functions (#3554)

The language specification suggests to add [five basic functions into the standard library](https://github.com/enso-org/design/blob/wip/wd/enso-spec/epics/enso-spec-1.0/05.%20Functions.md#useful-functions-in-the-standard-library). `identity`, `flip`, `const`, `curry` & `uncurry`.

# Important Notes
The new functions are being added into existing `Function.enso` file. That may not be the best place, but it is not clear from the [design spec](https://github.com/enso-org/design/blob/wip/wd/enso-spec/epics/enso-spec-1.0/05.%20Functions.md#useful-functions-in-the-standard-library) how they are supposed to be imported. I can move them wherever needed.

There is a documentation provided for each of the functions, but I am not sure how to verify it is correct. Do we generate the documentation for stdlib somehow?
This commit is contained in:
Jaroslav Tulach 2022-07-11 12:30:44 +02:00 committed by GitHub
parent 28513a3389
commit 735053c218
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 0 deletions

View File

@ -147,6 +147,7 @@
- [Added `File_Format.Delimited` support to `Table.write` for new files.][3528]
- [Adjusted `Database.connect` API to new design.][3542]
- [Added `File_Format.Excel` support to `Table.write` for new files.][3551]
- [identity,const,flip,curry,uncurry functions][3554]
- [Added append support for `File_Format.Excel`.][3558]
- [Added support for custom encodings in `File_Format.Delimited` writing.][3564]
- [Allow filtering caught error type in `Error.catch`.][3574]
@ -236,6 +237,7 @@
[3542]: https://github.com/enso-org/enso/pull/3542
[3551]: https://github.com/enso-org/enso/pull/3551
[3552]: https://github.com/enso-org/enso/pull/3552
[3554]: https://github.com/enso-org/enso/pull/3554
[3558]: https://github.com/enso-org/enso/pull/3558
[3564]: https://github.com/enso-org/enso/pull/3564
[3574]: https://github.com/enso-org/enso/pull/3574

View File

@ -1,3 +1,5 @@
import Standard.Base.Data.Vector
# 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
identity : a -> a
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
IO.println <| Function.flip (+) "world" "hello" # Prints 'helloworld'
flip : (a -> b -> c) -> (b -> a -> c)
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
IO.println <| [1, 2, 3].map (Function.const 7) # Prints '[7, 7, 7]'
const : a -> b -> a
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
curry : ([a, b] -> c) -> (a -> b -> c)
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
uncurry : (a -> b -> c) -> ([a, b] -> c)
uncurry f = (pair -> f pair.head pair.second)

View File

@ -403,6 +403,8 @@ final class SuggestionBuilder[A: IndexedSource](val source: A) {
val tdef = resolveTypeName(bindings, typeName)
.getOrElse(TypeArg.Value(QualifiedName.simpleName(typeName)))
args :+ tdef
case seq: IR.Application.Literal.Sequence =>
seq.items.foldLeft(args)((a, t) => go(t, a))
case _ =>
args
}

View File

@ -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 "identity" <|
Test.specify "identity on number" <|
(identity 5) . should_equal 5
Test.specify "identity on text" <|
(identity '5') . should_equal '5'
Test.specify "identity on boolean" <|
(identity False) . should_equal False
Test.group "flip" <|
Test.specify "flip on number" <|
(flip (-) 2 5) . should_equal 3
Test.specify "flip on text" <|
(flip (+) "world" "hello") . should_equal "helloworld"
Test.group "const" <|
Test.specify "const on number" <|
two = const 2
two 5 . should_equal 2
Test.group "curry" <|
Test.specify "curry on number list" <|
sum = x -> x.fold 0 (+)
sum [1, 2, 3, 4] . should_equal 10
plus = curry sum
plus 6 3 . should_equal 9
Test.group "uncurry" <|
Test.specify "uncurry on number list" <|
times = uncurry (*)
times [6, 7] . should_equal 42
main = Test.Suite.run_main spec

View File

@ -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
@ -66,6 +67,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