Откуда появился вариант [T] в Scala? - PullRequest
9 голосов
/ 07 февраля 2012

Я все еще новичок в разработке Scala, но я нашел концепцию Option [T] действительно потрясающей, особенно сопоставление с образцом при использовании с Some и None. Я даже реализую это в какой-то степени в проекте C #, над которым я сейчас работаю, но поскольку здесь нет соответствия шаблонам, это не так уж и здорово.

Реальный вопрос в том, где теория этого объекта? это что-то конкретное из Scala? Функциональные языки? Где я могу найти больше об этом?

Ответы [ 3 ]

13 голосов
/ 07 февраля 2012

Большую часть времени я думал, что он исходит из Хаскелла и имеет имя Может быть монада

Но после небольшого исследования ямы обнаружили, что в документах SML есть некоторые ссылки на типы опций, как говорит @ShiDoiSi.Более того, он имеет ту же семантику (Some / None), что и Scala.Самая старая бумага, которую мне удалось найти, это , что (около 89 г.) (см. Сноску на 6-й странице)

8 голосов
/ 07 февраля 2012

Вам не нужно сопоставление с образцом, чтобы использовать Option.Я написал это на C # для вас ниже.Обратите внимание, что функция Fold заботится обо всем, что в противном случае было бы сопоставлено с образцом.

Сопоставление с образцом обычно не рекомендуется в пользу комбинаторов более высокого уровня.Например, если ваша конкретная функция может быть написана с использованием Select, вы должны использовать ее вместо Fold (что эквивалентно сопоставлению с шаблоном).В противном случае, если исходить из кода, свободного от побочных эффектов (и, следовательно, по уравнениям), вы, по сути, будете заново реализовывать существующий код.Это относится ко всем языкам, не только к Scala или C #.

using System;
using System.Collections;
using System.Collections.Generic;

namespace Example {
  /// <summary>
  /// An immutable list with a maximum length of 1.
  /// </summary>
  /// <typeparam name="A">The element type held by this homogenous structure.</typeparam>
  /// <remarks>This data type is also used in place of a nullable type.</remarks>
  public struct Option<A> : IEnumerable<A> {
    private readonly bool e;
    private readonly A a;

    private Option(bool e, A a) {
      this.e = e;
      this.a = a;
    }

    public bool IsEmpty {
      get {
        return e;
      }
    }

    public bool IsNotEmpty{
      get {
        return !e;
      }
    }

    public X Fold<X>(Func<A, X> some, Func<X> empty) {
      return IsEmpty ? empty() : some(a);
    }

    public void ForEach(Action<A> a) {
      foreach(A x in this) {
        a(x);
      }
    }

    public Option<A> Where(Func<A, bool> p) {
      var t = this;
      return Fold(a => p(a) ? t : Empty, () => Empty);
    }

    public A ValueOr(Func<A> or) {
      return IsEmpty ? or() : a;
    }

    public Option<A> OrElse(Func<Option<A>> o) {
      return IsEmpty ? o() : this;
    }

    public bool All(Func<A, bool> f) {
      return IsEmpty || f(a);
    }

    public bool Any(Func<A, bool> f) {
      return !IsEmpty && f(a);
    }

    private A Value {
      get {
        if(e)
          throw new Exception("Value on empty Option");
        else
          return a;
      }
    }

    private class OptionEnumerator : IEnumerator<A> {
      private bool z = true;
      private readonly Option<A> o;
      private Option<A> a;

      internal OptionEnumerator(Option<A> o) {
        this.o = o;
      }

      public void Dispose() {}

      public void Reset() {
        z = true;
      }

      public bool MoveNext() {
        if(z) {
          a = o;
          z = false;
        } else
          a = Option<A>.Empty;

        return !a.IsEmpty;
      }

      A IEnumerator<A>.Current {
        get {
          return o.Value;
        }
      }

      public object Current {
        get {
          return o.Value;
        }
      }
    }

    private OptionEnumerator Enumerate() {
      return new OptionEnumerator(this);
    }

    IEnumerator<A> IEnumerable<A>.GetEnumerator() {
      return Enumerate();
    }

    IEnumerator IEnumerable.GetEnumerator() {
      return Enumerate();
    }

    public static Option<A> Empty {
      get {
        return new Option<A>(true, default(A));
      }
    }

    public static Option<A> Some(A t) {
      return new Option<A>(false, t);
    }
  }
}
7 голосов
/ 07 февраля 2012

Википедия - твой друг: http://en.wikipedia.org/wiki/Option_type

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