The function in map is pretty easy. I want to double every element in a list which can be done:
map(fn x => x * 2);
But what if I want to name this function double?
fun double = map(fn x => x * 2);
Calling this function I get
- double [1,2,3];
val it = fn : int list -> int list
How can I name this function double?
The result of map (fn x => x * 2) is a function, which can be bound to an identifier:
- val double = map (fn x => x * 2);
val double = fn : int list -> int list
- double [1,2,3];
val it = [2,4,6] : int list
The fun form is just syntactic sugar. For example:
fun name param = ...
will be desugared to:
val rec name = fn param => ...
The rec part is a keyword that lets you implement recursive function definitions.
Related
I have a reference to a functionthat needs a parameter.
fun foo(x: Int) = 2 * x
val f: KFunction1<Int, Int> = ::foo
Is there any way to write applyArgument where
val f2: KFunction0<Int> = f1.applyArgument(42)
assertEquals("foo", f2.name)
assertEquals(84, f2())
I don't want to use a callable reference, as I need access to the name property.
hope it helps you:
fun foo(x: Int) = 2 * x
val f1 = ::foo
val f0 = { -> f1(42) }
f0() //84
KFunctions are intented to represent functions that are explicitly decleared in Kotlin code, but f2 is not declared anywhere in the code. In addition KFunction has lot of reflection properties and functions which are not relevant to the applied function f2. Therefore even if it is possible it is not recommended.
If you want to do it anyway you can simply write an applyArgument function in this way:
fun <T, R> KFunction1<T, R>.applyArgument(value: T): KFunction0<R> {
return object : KFunction<R> by this, KFunction0<R> {
override fun invoke(): R {
return this#applyArgument(value)
}
}
}
But, if what you need is to preserve the name, I would do it in a safe way. One way could be:
data class Named<out T>(val name: String, val value: T)
fun <T, R> Named<T>.map(transform: (T) -> R): Named<R> = Named(name, transform(value))
val <F : KFunction<*>> F.named: Named<F>
get() = Named(name, this)
Then use it:
fun foo(x: Int) = 2 * x
val f: Named<(Int) -> Int> = ::foo.named
val f2: Named<() -> Int> = f.map { fValue -> { fValue(42) } }
assertEquals("foo", f2.name)
assertEquals(84, f2.value())
Partial application is possible.
You may just declare a function for partial application and use it for the :: reference.
Hence, the name would not be the original function. Another approach - create your own classes/interfaces
data class MyFunction1<T, R>(val name: String, val f: (T) -> R) {
operator fun invoke(t: T) = f(t)
}
data class MyFunction0<R>(val name: String, val f: () -> R) {
operator fun invoke() = f()
}
Now define the curring:
fun MyFunction1<T, R>.curry(t: T) = MyFunction0(name){ f(t) }
(it can be a member function too)
I was looking through array extension functions and found reduce() one
inline fun <S, T: S> Array<out T>.reduce(operation: (acc: S, T) -> S): S {
if (isEmpty())
throw UnsupportedOperationException("Empty array can't be reduced.")
var accumulator: S = this[0]
for (index in 1..lastIndex) {
accumulator = operation(accumulator, this[index])
}
return accumulator
}
here the accumulator variable of type S assigned with first element from the array with type T.
Can't wrap my head around the real use case of reduce() function with two data types. Here synthetic example which actually doesn't make any sense.
open class A(var width: Int = 0)
class B(width: Int) : A(width)
val array = arrayOf(A(7), A(4), A(1), A(4), A(3))
val res = array.reduce { acc, s -> B(acc.width + s.width) }
Seems most real life use cases with this function use this signature:
inline fun <T> Array<out T>.reduce(operation: (acc: T, T) -> T): T
Can you help with providing some examples, where reduce() function can be useful with different types.
Here is an example:
interface Expr {
val value: Int
}
class Single(override val value: Int): Expr
class Sum(val a: Expr, val b: Expr): Expr {
override val value: Int
get() = a.value + b.value
}
fun main(args: Array<String>) {
val arr = arrayOf(Single(1), Single(2), Single(3));
val result = arr.reduce<Expr, Single> { a, b -> Sum(a, b) }
println(result.value)
}
I'm trying to define a propositional logic valuation using SML structure. A valuation in propositional logic maps named variables (i.e., strings) to Boolean values.
Here is my signature:
signature VALUATION =
sig
type T
val empty: T
val set: T -> string -> bool -> T
val value_of: T -> string -> bool
val variables: T -> string list
val print: T -> unit
end;
Then I defined a matching structure:
structure Valuation :> VALUATION =
struct
type T = (string * bool) list
val empty = []
fun set C a b = (a, b) :: C
fun value_of [] x = false
| value_of ((a,b)::d) x = if x = a then b else value_of d x
fun variables [] = []
| variables ((a,b)::d) = a::(variables d )
fun print valuation =
(
List.app
(fn name => TextIO.print (name ^ " = " ^ Bool.toString (value_of valuation name) ^ "\n"))
(variables valuation);
TextIO.print "\n"
)
end;
So the valuations should look like [("s",true), ("c", false), ("a", false)]
But I can't declare like a structure valuation or make an instruction like: [("s",true)]: Valuation.T; When I tried to use the valuation in a function, I get errors like:
Can't unify (string * bool) list (*In Basis*) with
Valuation.T
Could someone help me? Thanks.
The type Valuation.T is opaque (hidden).
All you know about it is that it's called "T".
You can't do anything with it except through the VALUATION signature, and that signature makes no mention of lists.
You can only build Valuations using the constructors empty and set, and you must start with empty.
- val e = Valuation.empty;
val e = - : Valuation.T
- val v = Valuation.set e "x" true;
val v = - : Valuation.T
- val v2 = Valuation.set v "y" false;
val v2 = - : Valuation.T
- Valuation.value_of v2 "x";
val it = true : bool
- Valuation.variables v2;
val it = ["y","x"] : string list
- Valuation.print v2;
y = false
x = true
val it = () : unit
Note that every Valuation.T value is printed as "-" since the internal representation isn't exposed.
Suppose all I know about a function is that it is of type:
int list -> int * string -> int
Is there any way of knowing in advance whether this means:
(int list -> int * string) -> int or int list -> (int * string -> int)?
Thanks,
bclayman
-> is right associative in SML type annotations, so int list -> (int * string -> int) is correct.
Consider this simple experiment in the REPL:
- fun add x y = x+y;
val add = fn : int -> int -> int
add is a function which, when fed an int, returns a function, namely the function which sends y to x + y -- hence its type is int -> (int ->int). It isn't a function which, when a fed a function from ints to ints outputs an int (which is what (int -> int) -> int would be). A somewhat artificial example of the later sort of thing is:
- fun apply_to_zero_and_increment f = 1 + f(0);
val apply_to_zero_and_increment = fn : (int -> int) -> int
If I define fun g(x) = x + 5 then apply_to_zero_and_increment g returns 6.
If you have a recursive function that relies on some other function what is the preferred way to implement that?
1) outside the recursive function
let doSomething n = ...
let rec doSomethingElse x =
match x with
| yourDone -> ...
| yourNotDone -> doSomethingElse (doSomething x)
2) inside the recursive function
let rec doSomethingElse x =
let doSomething n = ...
match x with
| yourDone -> ...
| yourNotDone -> doSomethingElse (doSomething x)
3) encapsulate both inside the a third function
let doSomethingElse x =
let doSomething n = ...
let innerDoSomethingElse =
match x with
| yourDone -> ...
| yourNotDone -> innerDoSomethingElse (doSomething x)
4) something even better?
module Test =
let f x =
let add a b = a + b //inner function
add x 1
let f2 x =
let add a = a + x //inner function with capture, i.e., closure
add x
let outerAdd a b = a + b
let f3 x =
outerAdd x 1
Translates to:
[CompilationMapping(SourceConstructFlags.Module)]
public static class Test {
public static int f(int x) {
FSharpFunc<int, FSharpFunc<int, int>> add = new add#4();
return FSharpFunc<int, int>.InvokeFast<int>(add, x, 1);
}
public static int f2(int x) {
FSharpFunc<int, int> add = new add#8-1(x);
return add.Invoke(x);
}
public static int f3(int x) {
return outerAdd(x, 1);
}
[CompilationArgumentCounts(new int[] { 1, 1 })]
public static int outerAdd(int a, int b) {
return (a + b);
}
[Serializable]
internal class add#4 : OptimizedClosures.FSharpFunc<int, int, int> {
internal add#4() { }
public override int Invoke(int a, int b) {
return (a + b);
}
}
[Serializable]
internal class add#8-1 : FSharpFunc<int, int> {
public int x;
internal add#8-1(int x) {
this.x = x;
}
public override int Invoke(int a) {
return (a + this.x);
}
}
}
The only additional cost for an inner function is new'ing up an instance of FSharpFunc--seems negligible.
Unless you're very performance sensitive, I would go with the scope that makes the most sense, that is, the narrowest scope possible.