Any or a Trouble with Sequence of Functions

Making a sequence of functions in Python with different parameter values?

The problem you are seeing is because Python creates that reference to the name k and doesn't capture the value, so your code is equivalent to this code:

graph_fns = []

def knng(pts):
return get_knng_graph(pts,k)

for k in range(1,5):
graph_fns.append(knng);

If you want to bind the value of k to the function, there are a couple of solutions.

The most trivial code change is to add an extra argument with a default parameter:

graph_fns = []
for k in range(1,5):

def knng(pts, k=k):
return get_knng_graph(pts, k)

graph_fns.append(knng)

You might also find it a bit cleaner to use functools.partial:

from functools import partial

graph_fns = []

for k in range(1,5):
knng = partial(get_knng_graph, k=k)

graph_fns.append(knng)

and by that time you could just use a list comprehension:

from functools import partial

graph_fns = [partial(get_knng_graph, k=k) for k in range(1, 5)]

There are some other options discussed on this page, like creating a class for this.

How to apply a sequence of functions on a sequence of variables in Clojure?

Use juxt:

((juxt + max min) 2 3 5 1 6 4)
=> [21 6 1]

Or define function solution:

(defn solution
[& args]
(fn [& args2]
(apply (apply juxt args) args2)))

((solution + max min) 2 3 5 1 6 4)
=> [21 6 1]

TypeScript variadic tuple type inference issue, for function that runs a sequence of Result-returning functions

In cases like this it's definitely easier to go the route of your sequenceGeneric2, where you have a generic parameter directly corresponding to the type of the passed-in argument; after all, it's more straightforward for the compiler to infer the type T from a value of type T than it is for the compiler to infer the type T from a value of type Readonly<{[K in keyof T]: SomeFunction<T[K]>}>.

In your case you were going in the right direction with Fns, but you were still expecting the compiler to infer E, which it's just not in a good position to do, for the same reason that you couldn't infer the T tuple very well in sequenceGeneric1.


One more thing: if you pass an array literal into a function, there's a good chance that the compiler will infer an unordered array type for it instead of a tuple type. There are ways to give the compiler a hint that you'd prefer a tuple type to be inferred. One way is to use variadic tuple notation... so instead of writing fns: Fns, you can write fns: readonly [...Fns]. That doesn't make much difference in terms of what types fns can be, but it does cause the compiler to prefer tuple-typed Fns.


So, to proceed: Let's have only one generic type parameter, Fns, and then make the compiler calculate both the T types and the E type in the output:

declare function sequenceGeneric<Fns extends Array<() => Result<any, any>>>(
fns: readonly [...Fns],
): Result<
{ [P in keyof Fns]: ExtractResultSuccessType<Fns[P]> },
ExtractResultErrorType<Fns[keyof Fns]>
>;

where

type ExtractResultSuccessType<Fn> = Fn extends () => Result<infer T, any> ? T : never;
type ExtractResultErrorType<Fn> = Fn extends () => Result<any, infer E> ? E : never;

I've changed unknown in the inferred type to any because it tends to be easier for the compiler to verify. unknown is a true top type which sometimes behaves strictly with covariance/contravariance in a way you don't really want.


Let's see if it works:

function checkGeneric() {
return sequenceGeneric([f1, f2, f3]);
}
// function checkGeneric(): Result<[string, boolean, number], string>

Looks good!


Playground link to code

Apply a sequence of functions to value and get the final result

This should do it:

 pipeline.foldLeft(initial_value){case (acc, (k,obj)) => obj.func(acc)}

No idea why pipeline contains pairs, though.

Composing a sequence of functions that return future

How about this?

def doInOrder[T] (fs : (T => Future[T])*)(implicit ec:ExecutionContext): T=>Future[T] = {
t => fs.foldLeft(Future.successful(t))((acc, f) => acc.flatMap(f))
}


Related Topics



Leave a reply



Submit