Added 'Lambda with Receiver' samples
This commit is contained in:
parent
d1c7242fd1
commit
ea45a18ae9
|
@ -0,0 +1,32 @@
|
|||
// LocalFunctions/ReturningFunc.kt
|
||||
package lambdawithreceiver
|
||||
import atomictest.eq
|
||||
|
||||
fun first(): (Int) -> Int {
|
||||
val func = fun (i: Int): Int {
|
||||
return i + 1
|
||||
}
|
||||
func(1) eq 2
|
||||
return func // [1]
|
||||
}
|
||||
|
||||
fun second(): (String) -> String {
|
||||
val func2 = { s: String -> "$s!" }
|
||||
func2("abc") eq "abc!"
|
||||
return func2 // [1]
|
||||
}
|
||||
|
||||
fun third(): () -> String {
|
||||
fun greet() = "Hi!"
|
||||
return ::greet // [1]
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val firstFun: (Int) -> Int = first()
|
||||
val secondFun: (String) -> String = second()
|
||||
val thirdFun: () -> String = third()
|
||||
|
||||
firstFun(42) eq 43 // [2]
|
||||
secondFun("xyz") eq "xyz!" // [3]
|
||||
thirdFun() eq "Hi!" // [4]
|
||||
}
|
|
@ -18,3 +18,5 @@ files:
|
|||
visible: true
|
||||
- name: src/ReturnInsideLambda.kt
|
||||
visible: true
|
||||
- name: src/ReturningFunc.kt
|
||||
visible: true
|
||||
|
|
|
@ -4,7 +4,7 @@ The `createCounter()` function creates a pair of functions for managing the
|
|||
counter. Instead of creating a class, we manipulate with a counter using only
|
||||
functions.
|
||||
|
||||
In `createCounter` define a local variable `counter`. Then define two local
|
||||
In `createCounter` define a local variable `counter`. Then define two local
|
||||
functions:
|
||||
|
||||
- `inc()` - increases the `counter` value by one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## Local Functions (#3)
|
||||
|
||||
Complete the implementation of the `createContainer()` function. It returns
|
||||
Complete the implementation of the `createContainer()` function. It returns
|
||||
a pair of functions to control the integer container. The first function adds
|
||||
an integer element to the container, the second function removes an element
|
||||
from the container and returns it. If the container is empty, it returns `null`.
|
|
@ -0,0 +1,11 @@
|
|||
// LambdaWithReceiver/AnonymousFunction.kt
|
||||
package lambdawithreceiver
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
val divides = fun Int.(d: Int): Boolean {
|
||||
return this % d == 0
|
||||
}
|
||||
10.divides(2) eq true
|
||||
10.divides(3) eq false
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
// LambdaWithReceiver/BuildString.kt
|
||||
package buildstring
|
||||
import atomictest.eq
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
// LambdaWithReceiver/BuildStringDef.kt
|
||||
package buildstring
|
||||
|
||||
fun buildString(
|
||||
builderAction: StringBuilder.() -> Unit
|
||||
): String {
|
||||
val sb = StringBuilder()
|
||||
sb.builderAction() // [1]
|
||||
return sb.toString()
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
// LambdaWithReceiver/Declarations.kt
|
||||
package lambdawithreceiver
|
||||
import atomictest.eq
|
||||
|
||||
fun buildString1(
|
||||
builderAction:
|
||||
(StringBuilder) -> Unit // [1]
|
||||
): String {
|
||||
val sb = StringBuilder()
|
||||
builderAction(sb) // [2]
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun buildString2(
|
||||
builderAction:
|
||||
StringBuilder.() -> Unit // [3]
|
||||
): String {
|
||||
val sb = StringBuilder()
|
||||
sb.builderAction() // [4]
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun main() {
|
||||
buildString1 {
|
||||
it.append("Regular lambda")
|
||||
} eq "Regular lambda"
|
||||
|
||||
buildString2 {
|
||||
append("Lambda with receiver")
|
||||
} eq "Lambda with receiver"
|
||||
}
|
|
@ -1,9 +1,7 @@
|
|||
// LambdaWithReceiver/Extensions.kt
|
||||
package lambdawithreceiver
|
||||
package statemachine
|
||||
|
||||
fun StringBuilder.appendAlphabet() {
|
||||
this.append("Alphabet:") // Explicit
|
||||
for (ch in 'a'..'z') {
|
||||
append(ch) // Implicit
|
||||
}
|
||||
fun StateMachine.pauseAndResume() {
|
||||
this.pause() // Explicit
|
||||
resume() // Implicit
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
// LambdaWithReceiver/NestedLWR.kt
|
||||
package lambdawithreceiver
|
||||
import atomictest.eq
|
||||
|
||||
fun Int.ext(): String.() -> Unit {
|
||||
val func = lambda@ fun String.() {
|
||||
val d = this // func's receiver
|
||||
val d2 = this@lambda
|
||||
d eq d2
|
||||
}
|
||||
val func2 = { s: String ->
|
||||
// ext()'s receiver; enclosing
|
||||
// lambda doesn't have a receiver
|
||||
val d1 = this
|
||||
}
|
||||
"abc".func() // [1]
|
||||
func2("abc")
|
||||
return func // [2]
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val funcHere = 1.ext()
|
||||
"abc".funcHere() // [5]
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
// LambdaWithReceiver/NewStateMachine1.kt
|
||||
package statemachine
|
||||
|
||||
fun newStateMachine1(
|
||||
operate: (StateMachine) -> Unit
|
||||
) {
|
||||
val stateMachine = StateMachine()
|
||||
stateMachine.start()
|
||||
operate(stateMachine)
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
// LambdaWithReceiver/NewStateMachine2.kt
|
||||
package statemachine2
|
||||
import statemachine.StateMachine
|
||||
|
||||
fun newStateMachine1(
|
||||
operate: (StateMachine) -> Unit // [1]
|
||||
) {
|
||||
val stateMachine = StateMachine()
|
||||
stateMachine.start()
|
||||
operate(stateMachine) // [2]
|
||||
}
|
||||
|
||||
fun newStateMachine2(
|
||||
operate: StateMachine.() -> Unit // [3]
|
||||
) {
|
||||
val stateMachine = StateMachine()
|
||||
stateMachine.start()
|
||||
stateMachine.operate() // [4]
|
||||
}
|
||||
|
||||
fun main() {
|
||||
newStateMachine1 {
|
||||
it.finish()
|
||||
}
|
||||
newStateMachine2 {
|
||||
finish()
|
||||
}
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
// LambdaWithReceiver/RegularLambda.kt
|
||||
package regularlambda
|
||||
import atomictest.eq
|
||||
|
||||
fun buildStr(
|
||||
builderAction: (StringBuilder) -> Unit
|
||||
): String {
|
||||
val sb = StringBuilder()
|
||||
builderAction(sb)
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
fun main() {
|
||||
buildStr {
|
||||
it.append("Alphabet: ")
|
||||
for (ch in 'a'..'z') {
|
||||
it.append(ch)
|
||||
}
|
||||
} eq
|
||||
"Alphabet: abcdefghijklmnopqrstuvwxyz"
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// LambdaWithReceiver/StateMachine.kt
|
||||
package statemachine
|
||||
import statemachine.State.*
|
||||
|
||||
enum class State { ON, OFF, PAUSED }
|
||||
|
||||
class StateMachine {
|
||||
var state: State = OFF
|
||||
private set
|
||||
|
||||
private fun updateState(
|
||||
current: State?, new: State
|
||||
) {
|
||||
if (current == null || state == current) {
|
||||
println("$state -> $new")
|
||||
state = new
|
||||
}
|
||||
}
|
||||
|
||||
fun start() = updateState(OFF, ON)
|
||||
|
||||
fun pause() = updateState(ON, PAUSED)
|
||||
|
||||
fun resume() = updateState(PAUSED, ON)
|
||||
|
||||
fun finish() = updateState(null, OFF)
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
// LambdaWithReceiver/UseNewStateMachine1.kt
|
||||
package statemachine
|
||||
|
||||
fun main() {
|
||||
println("first")
|
||||
newStateMachine1 { sm -> // [1]
|
||||
sm.finish() // [2]
|
||||
}
|
||||
println("second")
|
||||
newStateMachine1 {
|
||||
it.pause() // [3]
|
||||
it.resume()
|
||||
it.finish()
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
first
|
||||
OFF -> ON
|
||||
ON -> OFF
|
||||
second
|
||||
OFF -> ON
|
||||
ON -> PAUSED
|
||||
PAUSED -> ON
|
||||
ON -> OFF
|
||||
*/
|
|
@ -0,0 +1,16 @@
|
|||
// LambdaWithReceiver/UseNewStateMachine2.kt
|
||||
package statemachine2
|
||||
|
||||
fun main() {
|
||||
newStateMachine2 { // [1]
|
||||
this.pause() // [2]
|
||||
resume() // [3]
|
||||
finish()
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
OFF -> ON
|
||||
ON -> PAUSED
|
||||
PAUSED -> ON
|
||||
ON -> OFF
|
||||
*/
|
|
@ -1,14 +1,22 @@
|
|||
type: theory
|
||||
files:
|
||||
- name: src/StringBuilder.kt
|
||||
- name: src/StateMachine.kt
|
||||
visible: true
|
||||
- name: src/RegularLambda.kt
|
||||
- name: src/UseNewStateMachine1.kt
|
||||
visible: true
|
||||
- name: src/BuildString.kt
|
||||
- name: src/NewStateMachine1.kt
|
||||
visible: true
|
||||
- name: src/UseNewStateMachine2.kt
|
||||
visible: true
|
||||
- name: src/Extensions.kt
|
||||
visible: true
|
||||
- name: src/Declarations.kt
|
||||
- name: src/NewStateMachine2.kt
|
||||
visible: true
|
||||
- name: src/NestedLWR.kt
|
||||
- name: src/AnonymousFunction.kt
|
||||
visible: true
|
||||
- name: src/StringBuilder.kt
|
||||
visible: true
|
||||
- name: src/BuildString.kt
|
||||
visible: true
|
||||
- name: src/BuildStringDef.kt
|
||||
visible: true
|
||||
|
|
|
@ -11,6 +11,6 @@ fun drawSquare(width: Int) = buildString {
|
|||
fun main() {
|
||||
drawSquare(3) eq
|
||||
"""|***
|
||||
|***
|
||||
|***""".trimMargin()
|
||||
|***
|
||||
|***""".trimMargin()
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
## Lambda with Receiver (#1)
|
||||
|
||||
Implement `drawSquare()` to return a square of star symbols in a `String`. It
|
||||
takes `width` as a parameter. For `width = 3` the following output is expected:
|
||||
Implement `drawSquare()` to return a square of star symbols in a `String`
|
||||
using `buildString`. `drawSquare()` takes `width` as a parameter. For
|
||||
`width = 3` the following output is expected:
|
||||
|
||||
```text
|
||||
***
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## Lambda with Receiver (#2)
|
||||
|
||||
Implement `buildList()` which is similar to `buildString()`. `buildList()`
|
||||
creates a mutable list and applies actions passed in a lambda parameter.
|
||||
Implement `buildMap()` which is similar to `buildList()`. `buildMap()`
|
||||
creates a mutable map and applies actions passed in a lambda parameter.
|
|
@ -4,14 +4,14 @@ import atomictest.eq
|
|||
|
||||
fun Window.dup() =
|
||||
Window("dup of $id").also {
|
||||
it.x = this.x // [1]
|
||||
it.x = this.x // [1]
|
||||
it.y = this.y
|
||||
it.w = this.w
|
||||
it.h = this.h
|
||||
}
|
||||
|
||||
fun Window.dup2() =
|
||||
Window("dup of $id").also { win ->
|
||||
Window("dup of $id").also { win -> // [2]
|
||||
win.x = this.x
|
||||
win.y = this.y
|
||||
win.w = this.w
|
||||
|
|
|
@ -10,8 +10,8 @@ data class Window( // [1]
|
|||
)
|
||||
|
||||
fun adjustWindowIfNotNull(window: Window?) {
|
||||
window?.run { // [2]
|
||||
this.x = 10 // [3]
|
||||
window?.run { // [1]
|
||||
this.x = 10 // [2]
|
||||
y = 10
|
||||
w *= 2
|
||||
h *= 2
|
||||
|
@ -23,4 +23,7 @@ fun main() {
|
|||
val windowOrNull: Window? = null
|
||||
adjustWindowIfNotNull(windowOrNull)
|
||||
println("Nothing happens")
|
||||
}
|
||||
}
|
||||
/* Output:
|
||||
Nothing happens
|
||||
*/
|
|
@ -1,4 +1,4 @@
|
|||
// MoreLibraryFunctions/ReadingName.kt
|
||||
// ScopeFunctions/ReadingName.kt
|
||||
fun main() {
|
||||
println("Enter your name:")
|
||||
readLine()
|
||||
|
|
|
@ -10,5 +10,5 @@ fun main() {
|
|||
remove(0)
|
||||
}
|
||||
result eq listOf(17, 42)
|
||||
mutableList eq listOf(17, 42)
|
||||
result eq mutableList
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
## The `with()` Function (#1)
|
||||
|
||||
Implement `buildString()` using `with()` helper function.
|
||||
Note that `with()` returns the result of the lambda.
|
||||
Implement `buildString()` using `with()` function from the Kotlin standard
|
||||
library. Note that `with()` defined in the library returns the result of the
|
||||
lambda.
|
|
@ -5,4 +5,4 @@ a lambda with receiver, implement the toy `with2()` function which
|
|||
takes an ordinary lambda as a parameter instead of a lambda with receiver.
|
||||
Note that there're no function analogous to `with2()` in the standard
|
||||
library, however, there're similar extension functions taking ordinary
|
||||
lambdas, as explained in [Library Helpers] atom.
|
||||
lambdas, as explained in [Scope Functions] atom.
|
|
@ -1,4 +1,4 @@
|
|||
// CheckInstructions/LocalFile.kt
|
||||
// CheckInstructions/DataFile.kt
|
||||
package checkinstructions
|
||||
import atomictest.eq
|
||||
import java.io.File
|
|
@ -2,7 +2,7 @@ type: theory
|
|||
files:
|
||||
- name: src/QuadraticRequire.kt
|
||||
visible: true
|
||||
- name: src/LocalFile.kt
|
||||
- name: src/DataFile.kt
|
||||
visible: true
|
||||
- name: src/GetTrace.kt
|
||||
visible: true
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// UnitTesting/StateMachine.kt
|
||||
package statemachine
|
||||
package unittesting
|
||||
|
||||
import statemachine.State.*
|
||||
import unittesting.State.*
|
||||
|
||||
enum class State { ON, OFF, PAUSED }
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// UnitTesting/TestStateMachine.kt
|
||||
package statemachine
|
||||
package unittesting
|
||||
import kotlin.test.*
|
||||
|
||||
class TestStateMachine {
|
||||
|
|
|
@ -3,7 +3,7 @@ package unittesting
|
|||
import kotlin.test.*
|
||||
|
||||
fun testFoo2() = expect(42, "Wrong answer") {
|
||||
foo()
|
||||
foo()
|
||||
}
|
||||
|
||||
fun main() {
|
||||
|
|
|
@ -1541,6 +1541,11 @@ public class TestAllExamples extends AbstractTestExamples {
|
|||
testExample("../AtomicKotlinCourse/Functional Programming/Local Functions/Examples/src/InterestingSessions.kt", localfunctions.InterestingSessionsKt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturningFunc() {
|
||||
testExample("../AtomicKotlinCourse/Functional Programming/Local Functions/Examples/src/ReturningFunc.kt", lambdawithreceiver.ReturningFuncKt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReturnFromFun() {
|
||||
testExample("../AtomicKotlinCourse/Functional Programming/Local Functions/Examples/src/ReturnFromFun.kt", ReturnFromFunKt::main);
|
||||
|
@ -2046,6 +2051,11 @@ public class TestAllExamples extends AbstractTestExamples {
|
|||
testExample("../AtomicKotlinCourse/Preventing Failure/Check Instructions/Examples/src/Postconditions.kt", checkinstructions.PostconditionsKt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDataFile() {
|
||||
testExample("../AtomicKotlinCourse/Preventing Failure/Check Instructions/Examples/src/DataFile.kt", checkinstructions.DataFileKt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSingleArgRequire() {
|
||||
testExample("../AtomicKotlinCourse/Preventing Failure/Check Instructions/Examples/src/SingleArgRequire.kt", checkinstructions.SingleArgRequireKt::main);
|
||||
|
@ -2061,11 +2071,6 @@ public class TestAllExamples extends AbstractTestExamples {
|
|||
testExample("../AtomicKotlinCourse/Preventing Failure/Check Instructions/Examples/src/QuadraticRequire.kt", checkinstructions.QuadraticRequireKt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLocalFile() {
|
||||
testExample("../AtomicKotlinCourse/Preventing Failure/Check Instructions/Examples/src/LocalFile.kt", checkinstructions.LocalFileKt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFail() {
|
||||
testExample("../AtomicKotlinCourse/Preventing Failure/The Nothing Type/Examples/src/Fail.kt", nothingtype.FailKt::main);
|
||||
|
@ -2132,18 +2137,18 @@ public class TestAllExamples extends AbstractTestExamples {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testRegularLambda() {
|
||||
testExample("../AtomicKotlinCourse/Power Tools/Lambda with Receiver/Examples/src/RegularLambda.kt", regularlambda.RegularLambdaKt::main);
|
||||
public void testNewStateMachine2() {
|
||||
testExample("../AtomicKotlinCourse/Power Tools/Lambda with Receiver/Examples/src/NewStateMachine2.kt", statemachine2.NewStateMachine2Kt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBuildString() {
|
||||
testExample("../AtomicKotlinCourse/Power Tools/Lambda with Receiver/Examples/src/BuildString.kt", BuildStringKt::main);
|
||||
testExample("../AtomicKotlinCourse/Power Tools/Lambda with Receiver/Examples/src/BuildString.kt", buildstring.BuildStringKt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeclarations() {
|
||||
testExample("../AtomicKotlinCourse/Power Tools/Lambda with Receiver/Examples/src/Declarations.kt", lambdawithreceiver.DeclarationsKt::main);
|
||||
public void testUseNewStateMachine2() {
|
||||
testExample("../AtomicKotlinCourse/Power Tools/Lambda with Receiver/Examples/src/UseNewStateMachine2.kt", statemachine2.UseNewStateMachine2Kt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -2152,8 +2157,13 @@ public class TestAllExamples extends AbstractTestExamples {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testNestedLWR() {
|
||||
testExample("../AtomicKotlinCourse/Power Tools/Lambda with Receiver/Examples/src/NestedLWR.kt", lambdawithreceiver.NestedLWRKt::main);
|
||||
public void testAnonymousFunction() {
|
||||
testExample("../AtomicKotlinCourse/Power Tools/Lambda with Receiver/Examples/src/AnonymousFunction.kt", lambdawithreceiver.AnonymousFunctionKt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseNewStateMachine1() {
|
||||
testExample("../AtomicKotlinCourse/Power Tools/Lambda with Receiver/Examples/src/UseNewStateMachine1.kt", statemachine.UseNewStateMachine1Kt::main);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in New Issue