1

If papply returns a function of less arity than an input function, is there a similar FP operation with returns a function which returns a value regardless of the value of the input function? If so, is there a C# equivalent?

Consider a C# function that returns void which you want to convert into an expression, and you've done this many many times by writing an anonymous function wrapper like (args) => f(args); return null;.

In C#,

public Func<T1, T2, ..., T8, TResult> WhatIsMyName<T1, T2, ..., T8, TResult> (Action<T1, T2, ..., T8> action, TResult value = default(TResult))
{
    return (t) => { action(t); return value; }
}

which you would ideally call like FP.WhatIsMyName(voidfunc) and so avoid having to cast.

In Clojure,

(defn whatismyname? [f x] 
  (f)
  x)
kotarak
  • 17,099
  • 2
  • 49
  • 39
davidzarlengo
  • 820
  • 1
  • 5
  • 16

2 Answers2

2

In functional programming, you'd probably use function composition to augment or modify a result. For your example, you simply compose the existing function with a constant one, e.g. given f:

val f' = const 0 o f

where o is function composition (like in math) and const 0 creates a constant function always returning 0 (for any argument). Those are standard combinators, which you can define as follows:

fun (g o f) x = g (f x)
fun const x y = x
Andreas Rossberg
  • 34,518
  • 3
  • 61
  • 72
  • Function composition seems like it's on the right track. Do you know if there is a way to set this up in C# built into the standard library? – davidzarlengo Mar 21 '12 at 17:49
  • 1
    @davidzarlengo: The only functional things in C# are related to LINQ, so very few of the standard methods are available. F# has lots if you are looking for a language in .NET that is designed for functional programming. – Guvante Mar 21 '12 at 18:03
1

You could write a method that creates the anonymous function for you.

public Action<T> Ignore<T,TResult>(Func<T,TResult> func)
{
    return (args) => { func(args); return; }
}

Although your code technically returns args, which would be the following format.

public Func<T,T> Ignore<T,TResult>(Func<T,TResult> func)
{
    return (args) => { func(args); return args; }
}

In either case you can pass it into another method like this Method(Ignore(DoSomething)); or you can call it yourself like this Ignore(DoSomething)(1);.

Guvante
  • 18,775
  • 1
  • 33
  • 64
  • I'm willing to write a method, if necessary, if I know what to name it. – davidzarlengo Mar 21 '12 at 17:48
  • @davidzarlengo: The method you wrote seems to work, you would just have to write it once for each arrity. (Generics can't support variable number of inputs) – Guvante Mar 21 '12 at 18:05
  • I ended up just writing another anonymous lambda returning null. I don't think C# is expressive enough to remove this kind of duplication. – davidzarlengo Mar 22 '12 at 16:47