Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Learning Haskell: list comprehensions in C#

Tags:

c#

linq

haskell

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?

like image 730
BM. Avatar asked Dec 04 '09 21:12

BM.


People also ask

Does Haskell support list comprehension?

Not to be outdone in terseness, Haskell has a further refinement of do-notation specifically for lists: Haskell's list comprehensions. List comprehensions provide an even simpler way of generating lists than do-notation.

How do I sort a list in Haskell?

Whenever we want to sort the elements of a given list, then we make use of the sort function in Haskell programming language, and the name of the list consisting of elements that are to be sorted is passed as a parameter to the sort function and the sort function takes a list as the input and returns the sorted list as ...


3 Answers

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
like image 160
dtb Avatar answered Nov 09 '22 14:11

dtb


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).

like image 32
3 revs, 2 users 97% Avatar answered Nov 09 '22 15:11

3 revs, 2 users 97%


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();
like image 39
Paul Rohde Avatar answered Nov 09 '22 15:11

Paul Rohde