SORU
23 Mart 2010, Salı


'Desen Eşleştirme' fonksiyonel dillerde nedir?

Fonksiyonel programlama hakkında bir kitap okuyorum ve fark ettimDesen Eşleştirmefonksiyonel dillerin temel özelliklerinden biri olarak birçok makale belirtilir.

Birisi açıklamak için Java/C /JavaScript geliştirici ne anlama geliyor olabilir?

CEVAP
23 Mart 2010, Salı


Anlayış desen eşleştirme üç bölümden açıklamam gerekir:

  1. Cebirsel veri türleri.
  2. Desen eşleştirme
  3. Onun korku neden.

Özetle veri türleri cebirsel

ML-senin gibi basit veri türlerini tanımlamak izin işlevsel dil denilen "ayrık sendikalar" veya "cebirsel veri türleri". Bu veri yapıları basit kaplar ve özyinelemeli olarak tanımlanabilir. Örneğin:

type 'a list =
    | Nil
    | Cons of 'a * 'a list

tanımlar yığını gibi bir veri yapısı. Bu C eşdeğer olarak düşün#:

public abstract class List<T>
{
    public class Nil : List<T> { }
    public class Cons : List<T>
    {
        public readonly T Item1;
        public readonly List<T> Item2;
        public Cons(T item1, List<T> item2)
        {
            this.Item1 = item1;
            this.Item2 = item2;
        }
    }
}

Yani, Cons Nil tanımlayıcılar basit of x * y * z * ... yapıcı ve bazı veri türlerini tanımlayan basit bir sınıfı tanımlar. Kurucu parametreleri isimsiz, pozisyon ve veri türü tespit ediyorlar.

Gibi a list sınıfınızın örneklerini oluşturun:

let x = Cons(1, Cons(2, Cons(3, Cons(4, Nil))))

Aynıdır:

Stack<int> x = new Cons(1, new Cons(2, new Cons(3, new Cons(4, new Nil()))));

Özetle, desen eşleştirme

Desen eşleştirme türü test türüdür. Hadi şöyle: yığın, peek yöntemleri uygulamak ve yığın alabiliriz yukarıdaki gibi bir nesne oluşturduk diyelim

let peek s =
    match s with
    | Cons(hd, tl) -> hd
    | Nil -> failwith "Empty stack"

let pop s =
    match s with
    | Cons(hd, tl) -> tl
    | Nil -> failwith "Empty stack"

Yukarıdaki yöntemler eşdeğer olarak uygulanan olmasa da) aşağıdaki C#:

public static T Peek<T>(Stack<T> s)
{
    if (s is Stack<T>.Cons)
    {
        T hd = ((Stack<T>.Cons)s).Item1;
        Stack<T> tl = ((Stack<T>.Cons)s).Item2;
        return hd;
    }
    else if (s is Stack<T>.Nil)
        throw new Exception("Empty stack");
    else
        throw new MatchFailureException();
}

public static Stack<T> Pop<T>(Stack<T> s)
{
    if (s is Stack<T>.Cons)
    {
        T hd = ((Stack<T>.Cons)s).Item1;
        Stack<T> tl = ((Stack<T>.Cons)s).Item2;
        return tl;
    }
    else if (s is Stack<T>.Nil)
        throw new Exception("Empty stack");
    else
        throw new MatchFailureException();
}

(Hemen hemen her zaman, diller desen eşleştirme uygulamak MLolmadan-çalışma zamanı tip testleri veya atmalarını, bu yüzden C# kod biraz aldatıcı. Bu uygulama ayrıntıları el sallayarak lütfen bazı: bir kenara fırça) )

Özetle veri yapısı ayrışma

Tamam, peek yöntemi geri dönelim:

let peek s =
    match s with
    | Cons(hd, tl) -> hd
    | Nil -> failwith "Empty stack"

Hile hd tl tanımlayıcılar değişken olduğunu anlamaktır (...değişmez, çünkü onlar gerçek değil, "değişken", ama "";) değerler ). errm Eğer s türü Cons, kurucu kendi değerlerini çekin ve değişkenleri hd tl adında onları bağlamak için gidiyoruz.

Desen eşleştirme tarafından bir veri yapısı bizi ayrıştırmak sağlar çünkü yararlıdırşekilonun yerineiçindekiler. Bu yüzden biz aşağıdaki gibi ikili bir ağaç define düşünün

type 'a tree =
    | Node of 'a tree * 'a * 'a tree
    | Nil

Şöyle: tree rotations bazı tanımlayabiliriz

let rotateLeft = function
    | Node(a, p, Node(b, q, c)) -> Node(Node(a, p, b), q, c)
    | x -> x

let rotateRight = function
    | Node(Node(a, p, b), q, c) -> Node(a, p, Node(b, q, c))
    | x -> x

(let rotateRight s = match s with .... let rotateRight = function kurucu sözdizimi şeker)

Değişkenler için veri yapısı bağlama ek olarak, aynı zamanda bu detaya. Hadi 31* *bir düğüm var ki. Eğer rotateLeft x, ararsak doğru çocuk Node yerine 34* *türü vardır, çünkü maç başarısız olan ilk desen karşı x, test ederiz. Herhangi bir giriş maç ve değiştirilmemiş dönecektir sonraki desen, x -> x, taşıyın.

Karşılaştırma için, yukarıdaki yöntemler C yazabilirdik# gibi:

public abstract class Tree<T>
{
    public abstract U Match<U>(Func<U> nilFunc, Func<Tree<T>, T, Tree<T>, U> nodeFunc);

    public class Nil : Tree<T>
    {
        public override U Match<U>(Func<U> nilFunc, Func<Tree<T>, T, Tree<T>, U> nodeFunc)
        {
            return nilFunc();
        }
    }

    public class Node : Tree<T>
    {
        readonly Tree<T> Left;
        readonly T Value;
        readonly Tree<T> Right;

        public Node(Tree<T> left, T value, Tree<T> right)
        {
            this.Left = left;
            this.Value = value;
            this.Right = right;
        }

        public override U Match<U>(Func<U> nilFunc, Func<Tree<T>, T, Tree<T>, U> nodeFunc)
        {
            return nodeFunc(Left, Value, Right);
        }
    }

    public static Tree<T> RotateLeft(Tree<T> t)
    {
        return t.Match(
            () => t,
            (l, x, r) => r.Match(
                () => t,
                (rl, rx, rr) => new Node(new Node(l, x, rl), rx, rr))));
    }

    public static Tree<T> RotateRight(Tree<T> t)
    {
        return t.Match(
            () => t,
            (l, x, r) => l.Match(
                () => t,
                (ll, lx, lr) => new Node(ll, lx, new Node(lr, x, r))));
    }
}

Cidden.

Desen eşleştirme harika

Bir şey uygulayabilirsinizbenzerC desen eşleştirme için# visitor pattern ama etkili bir şekilde ayırabilirsiniz. çünkü yaklaşık olarak esnek değil, karmaşık veri yapılarını kullanarak Eğer desen eşleştirme kullanıyorsanız ayrıca,,derleyici eğer bir durumda bıraktın. Ne muhteşem değil mi?

C dilinde benzer bir işlevi uygulamak istiyorum nasıl düşünün# veya desen eşleştirme olmadan dil. Test-test olmadan bunu yapmak istiyorum nasıl düşünün ve zamanında atmalarını. Onun kesinlikle değilzorsadece ağır ve hantal. Ve derleyici her durumda kapalı ettik emin olmak için kontrol yok.

Desen eşleştirme ve çok kullanışlı, kompakt bir sözdizimi veri yapıları ayrıştırmak gezinmek yardımcı kontrol derleyici sağlarmantıkkodunuzu, en azından biraz. Gerçektenkatil bir özellik.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • FRED

    FRED

    1 EKİM 2005
  • iNCH

    iNCH

    20 Temmuz 2009
  • tinycammonitor

    tinycammonit

    14 Aralık 2010