tags:

views:

434

answers:

4

The following code is in Haskell. How would I write similar function in C#?

squareArea xs = [pi * r^2 | r <- xs]

Just to clarify... above code is a function, that takes as input a list containing radius of circles. The expression calculates area of each of the circle in the input list.

I know that in C#, I can achieve same result, by looping thru a list and calculate area of each circle in the list and return a list containing area of circles. My question is... Can the above code be written in similar fashion in C#, perhaps using lambda expressions or LINQ?

+5  A: 
xs.Select(r => 2 * Math.PI * r * r)

is the right-hand side, I think (writing code in my browser, not compiled).

In general a Haskell list comprehension of the form

[e | x1 <- x1s, x2 <- x2s, p]

is probably something like

x1s.SelectMany(x1 =>
x2s.SelectMany(x2 =>
if p then return Enumerable.Singleton(e) else return Enumerable.Empty))

or

from x1 in x1s
from x2 in x2s
where p
select e

or something. Darn, I don't have time to fix it up now, someone else please do (marked Community Wiki).

Brian
+20  A: 

Using Enumerable:

IEnumerable<double> SquareArea(IEnumerable<int> xs)
{
    return from r in xs select Math.PI * r * r;
}

or

IEnumerable<double> SquareArea(IEnumerable<int> xs)
{
    return xs.Select(r => Math.PI * r * r);
}

which is very close to Haskell's

squareArea xs = map (\r -> pi * r * r) xs
dtb
wouldn't it be simpler to not use Lambda expressions?`squareArea xs = map (2*pi*) xs`
Jonno_FTW
Sure. You can even shorten it `squareArea = map (2*pi*)` But that's not very close to C# any more.
dtb
or `squareArea = map ((*pi).(^2))` with the correct formula
dtb
+4  A: 

dtb probably has the best version so far, but if you took it a bit further and put the methods in a static class and added the this operator like the following you could call the methods as if they were a part of your list:

public static class MyMathFunctions
{
    IEnumerable<double> SquareArea(this IEnumerable<int> xs)
    {
        return from r in xs select 2 * Math.PI * r * r;
    }

    IEnumerable<double> SquareAreaWithLambda(this IEnumerable<int> xs)
    {
        return xs.Select(r => 2 * Math.PI * r * r);
    }

}

Which could then be executed like this:

var myList = new List<int> { 1,2,3,4,5 };

var mySquareArea = myList.SquareArea();
Paul Rohde
Are both your SquareArea methods the same? My eye's can't spot the difference:(
chollida
Yes, I meant to include the:from r in xs select 2 * Math.PI * r * r;in the first method, I've edited my post to reflect it.
Paul Rohde
+1  A: 
Func<IEnumerable<Double>, IEnumerable<Double>> 
   squareArea =  xs => xs.Select(r => Math.PI*r*r);
primodemus