سؤال

let myFunc x y =
    List.fold (&&) true [func1 x y; func2 x y]

I don't know all the different operators and techniques in F#, but was hoping I could just plop some operator in place of "x y" for func1 and func2 to indicate to them "Just take my parameters" almost like how composition has implicit parameter pass through.

Alternatively, if someone can think of a much more straightforward and clean way of doing this that gets rid of the need for my function to hand it's parameters in, let me know.

Also, if this is just not possible which seems entirely likely, let me know.

Thanks!

هل كانت مفيدة؟

المحلول

I don't think there is a nice way to thread the parameters of myfunc to the parameters of func1 and func2. However, your example is perhaps a bit over-simplified, because you could just write:

let myfunc x y = 
  func1 x y && func2 x y

I suppose that in reality, you have a larger number of functions and then using fold makes a good sense. In that case, you could use fold to combine the functions rather than using it to combine the results.

If I simplify the problem a little and assume that func1 and func2 take the two arguments as a tuple (instead of taking them as two separate arguments), then you can write something like this:

let func1 (a, b) = true
let func2 (a, b) = true

let myfunc = List.fold (fun f st a -> f a && st a) (fun _ -> true) [ func1; func2 ] 

Now you do not need to pass the parameters around explicitly (to func1 and func2), but the arguments of fold got a bit more complicated. I think that's fine, because you need to write that just once (and it is quite readable this way).

However, if you're fan of the point-free style (or just want to see how far you could get), you can define a few helper functions and then write the code as follows:

/// Given a value, returns a constant function that always returns that value
let constant a _ = a
/// Takes an operation 'a -> b -> c' and builds a function that
/// performs the operation on results of functions    
let lift2 op f g x = op (f x) (g x)

let myfunc2  = List.fold (lift2 (&&)) (constant true) [ ffunc1; ffunc2 ] 

If you do not need arbitrary number of functions, then I'd simplify the code and not use fold at all. If you need to do that, then I think your version is very readable and not too long. The examples I wrote in this answer show that you can avoid passing the parameters by hand, but it makes the code a bit cryptic.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top