How to make a simple style with a long list of options

I have a function that creates an Async workflow and a function that takes 10 arguments in curry style. eg.

let createSequenceCore abcdefghij = async { ... } 

I want to create another function to start a workflow, so I have

 let startSequenceCore abcdefghij = Async.StartImmediate (createSequenceCore abcdefghij) 

Is there any way to get rid of these redundant parameters? I tried the << operator, but that only allows me to delete it.

 let startSequenceCore abcdefghi = Async.StartImmediate << (createSequenceCore abcdefghi) 

(I added Haskell and Scala to this question, even if the F # code itself, since really what I want is just how to make this kind of currying that applies to anyone, I would think that Haskell or Scala is the answer will be easily portable to F # and may be marked as the correct answer).

NOTE It is reasonably good to show that there is no easy solution for this, you can also get a reward.


UPDATE geesh. I will not give 100 points to answers that argue with the question, but do not answer it, even if it is considered the highest, so here:

I have a function that creates an Async workflow and a function that takes 4 arguments in curry style. eg.

 let createSequenceCore abcd = async { ... } 

I want to create another function to start a workflow, so I have

 let startSequenceCore abcd = Async.StartImmediate (createSequenceCore abcd) 

Is there any way to get rid of these redundant parameters? I tried the << operator, but that only allows me to delete it.

 let startSequenceCore abc = Async.StartImmediate << (createSequenceCore abc) 
+6
source share
4 answers

10 arguments sound like too much ... How about creating a record with 10 properties, or maybe DU, where you don't need all 10 in each case? In any case, you will get one argument this way, and the normal functional composition will work as expected.

EDIT:. When you really need it, you can create a more powerful version of the << and >> operators:

 let (<.<) f = (<<) (<<) (<<) f let (<..<) f = (<<) (<<) (<.<) f let (<...<) f = (<<) (<<) (<..<) f let flip fab = fba let (>.>) f = flip (<.<) f let (>..>) f = flip (<..<) f let (>...>) f = flip (<...<) f 

and then you can simply write:

 let startSequenceCore = Async.StartImmediate <...< createSequenceCore 

or

 let startSequenceCore = createSequenceCore >...> Async.StartImmediate 

PS: There is an argument f , so type inference contains general arguments, not obj .

+9
source

As @Daniel Fabian mentioned, 10 arguments are too many. In my experience, even 5 arguments is too much, and the code becomes unreadable and error prone. The presence of such functions usually indicates a poor design. See Also. Are there any recommendations regarding how many parameters a function should take?

However, if you insist, you can make it silent, although I doubt it is beneficial. I will give an example in Haskell, but I find it easy to port to F # as well. The trick is to nest the composition composition operator:

 data Test = Test deriving (Show) createSequenceCore :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Test createSequenceCore abcdefghij = Test -- the original version startSequenceCore :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> IO () startSequenceCore abcdefghij = print (createSequenceCore abcdefghij) -- and point-free: startSequenceCore' :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> IO () startSequenceCore' = (((((((((print .) .) .) .) .) .) .) .) .) . createSequenceCore 

Replacing f with (f .) Cancels the function for working with a single argument inside, as we see, adding parentheses to the type (.) :

 (.) :: (b -> c) -> ((a -> b) -> (a -> c)) 

See also this coverage blog post by Conal Elliot: Semantic Editor Combinators

+6
source

You can put arguments in createSequenceCore :

 let createSequenceCore(a, b, c, d, e, f, g, h, i, j) = async { ... } let startSequenceCore = createSequenceCore >> Async.StartImmediate 
+2
source

I assume that you just want to write clean code, and not allow currying one parameter at a time.

Just write your own composeN function.

 let compose4 gf x0 x1 x2 x4 = g (f x0 x1 x2 x4) let startSequenceCore = compose4 Async.StartImmediate createSequenceCore 
+1
source

All Articles