Некоторые функции F #, которые я хотел бы видеть в C # - PullRequest
4 голосов
/ 17 марта 2010

После возни с F # есть некоторые действительно приятные функции, которые, я думаю, мне не хватит, когда я ДОЛЖЕН вернуться к C #, какие-либо подсказки о том, как я могу отказаться от следующего, или, что еще лучше, дублирую их функциональность:

  • Сопоставление с образцом (особенно с дискриминационными союзами)
  • Дискриминационные союзы
  • Рекурсивные функции (головы и хвосты в списках)

И последнее, но не менее важное - обработка сообщений, вдохновленная Эрлангом.

Ответы [ 4 ]

7 голосов
/ 17 марта 2010

Используйте F # для создания повторно используемых библиотек, которые можно вызывать из C # .

Одна очень приятная вещь в F # - это то, что это все еще язык .NET. Вы можете смешивать и сопоставлять языки в CLR столько раз, сколько захотите ...

2 голосов
/ 17 марта 2010

Дискриминационные объединения и сопоставление с образцом можно смоделировать в C #, хотя определения типов немного многословны (см. Как я могу продублировать тип распознавания F # в C #? для некоторых идей). Вот подход, который я отстаивал в этом вопросе: тип F # type T = ACase of A | BCase of B | CCase of C может быть представлен абстрактным классом C # с некоторыми статическими вспомогательными методами.

public abstract class T {
    public abstract X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase);

    private class ACase : T {
        private A a;
        public ACase(A a) { this.a = a; }

        public override X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase) {
            return aCase(a);
        }
    }
    private class BCase : T {
        private B b;
        public BCase(B b) { this.b = b; }

        public override X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase) {
            return bCase(b);
        }
    }
    private class CCase : T {
        private C c;
        public CCase(C c) { this.c = c; }

        public override X Match<X>(Func<A,X> aCase, Func<B,X> bCase, Func<C,X> cCase) {
            return cCase(c);
        }
    }

    public static T MakeACase(A a) { return new ACase(a); }
    public static T MakeBCase(B b) { return new BCase(b); }
    public static T MakeCCase(C c) { return new CCase(c); }
}

Соответствие теперь похоже на F #, но без меток регистра. Эквивалент этого кода F #:

function
| A a -> 1
| B b -> 2
| C c -> 3

Это код C #:

public static int MatchDemo(T t) {
    return t.Match(
        a => 1,
        b => 2,
        c => 3);
}
2 голосов
/ 17 марта 2010

Я не уверен, в какой степени это действительно вопрос. Однако вот некоторые типичные шаблоны, которые я использую для кодирования этих функциональных конструкций в C # (некоторые из них взяты из моей книги, в которой имеется исходный код ).

Дискриминационные объединения - действительно, нет хорошего способа реализовать дискриминационные объединения в C # - единственное, что вы можете сделать, это реализовать их как иерархию классов (с базовым классом, представляющим тип DU, и производный класс для каждого случая DU). Вы также можете добавить свойство Tag (некоторого типа enum) к базовому классу, чтобы упростить проверку того, какой случай представляет класс. Насколько я знаю, это используется в деревьях выражений LINQ (которые действительно должны быть различены как объединение).

Сопоставление с образцом - вы, вероятно, никогда не получите это полностью общим способом (например, с вложенными образцами), но вы можете смоделировать сопоставление с образцом на различимых объединениях, подобных этому (используя тип Option<int>, который либо Some of int, либо None):

Option<int> value = GetOption();
int val;
if (value.TryMatchSome(out val)) 
  Console.WriteLine("Some {0}", val);
else if (value.TryMatchNone()) 
  Console.WriteLine("None");

Не идеально, но, по крайней мере, вы получаете относительно хороший способ извлечения значений из дел.

Передача сообщений - существует Время выполнения параллелизма и координации , которое в некоторых отношениях также основано на передаче сообщений и может использоваться в C #. Могу поспорить, что вы также можете использовать процессор почтовых ящиков F # из C #, используя технику, основанную на итераторах, которую я описал в этой статье , и которая также используется в библиотеке Wintellect PowerThreading. Тем не менее, я не думаю, что кто-то реализовал надежную библиотеку передачи сообщений, основанную на этой идее.

Таким образом, вы можете смоделировать многие функциональные возможности в C #, по крайней мере, в некоторой степени и использовать другие без каких-либо проблем (лямбда-функции и функции высшего порядка). Однако, если вам нужна вся мощь F #, вам просто нужно убедить вашу компанию начать использовать F #: -).

0 голосов
/ 17 марта 2010

Выезд

идея переключения / сопоставления с образцом

о некоторых безумных способах попытки сопоставления с образцом в C #.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...