برنامه نویسی

قدرت ترکیب تابع – برای یافتن اینکه آیا یک آرایه خاص است یا خیر

Summarize this content to 400 words in Persian Lang
من در ابتدا نسخه توسعه یافته این پست را در وبلاگم قرار دادم.

ارسال نتیجه یک تابع به دیگری تنها راه برای ترکیب دو تابع نیست.

از کلاس های ریاضی، ما به نوشتن دو تابع مانند این عادت کرده ایم compose(f, g) = x => f(g(x)). اما به نظر می رسد راه های بیشتری وجود دارد.

این نکته اصلی من از سخنرانی “قدرت ترکیب عملکرد” ​​توسط Conor Hoekstra در کنفرانس NDC 2024 است. درصورتی‌که می‌خواهید تماشا کنید، ضبط YouTube اینجاست.

بحث نشان می‌دهد که چگونه می‌توان با استفاده از زبان‌هایی مانند پایتون، هسکل و سایر زبان‌های مبهم و باطنی، مشخص کرد که آیا یک آرایه خاص است یا نه.

اینها درسهایی هستند که من یاد گرفتم و چند نمونه کد را به سی شارپ ترجمه کردم.

یک راه حل ساده برای یافتن اینکه آیا یک آرایه خاص است یا خیر

بیایید دریابیم که آیا یک آرایه خاص است یا خیر.

یک آرایه خاص است اگر هر جفت عنصر متوالی شامل دو عدد با برابری متفاوت باشد. به عنوان مثال، [4,3,1,6] خاص نیست دارای سه جفت است: 4,3، 3,1، و 1,6. جفت دوم دارای دو عدد فرد است که باعث می شود آرایه ما “خاص” نباشد.

اگر می خواهید خودتان آن را امتحان کنید، مشکل LeetCode در اینجا وجود دارد.

و این راه حل من قبل از استفاده از هر یک از مفاهیم جدید سخنرانی است،

IEnumerable<(int First, int Second)> Pairs(int[] array)
{
for (int i = 0; i < array.Length – 1; i++)
{
yield return (array[i], array[i + 1]);
}
// Or simply:
// return array.Zip(array.Skip(1));
}

bool HasDifferentParity((int First, int Second) pair)
=> pair.First % 2 != pair.Second % 2;

bool IsSpecial(int[] array)
=> Pairs(array).All(HasDifferentParity);

IsSpecial([1, 2, 3, 4]) // true
IsSpecial([4, 3, 1, 6]) // false

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

استفاده می کند Pairs() برای تولید جفت عناصر متوالی، HasDifferentParity() برای پیدا کردن اینکه هر دو عدد در یک جفت زوج هستند یا فرد، و All() از LINQ. هیچ چیز فانتزی نیست!

به غیر از ترکیب “معمول”، روش های دیگری برای ترکیب توابع وجود دارد

در اینجا تعدادی از آنها به صورت شبه کد آورده شده است:

def i(x) = x
def k(x, y) = x
def ki(x, y) = y

def s(f, g) = \x => f(x, g(x))
def b(f, g) = \x => f(g(x)) // 👈

def c(f) = \x, y => f(y, x)
def w(f) = \x => f(x, x)

def d(f, g) = \x, y => f(x, g(y))
def b1(f, g) = \x, y => f(g(x, y))
def psi(f, g) = \x, y => f(g(x), g(y)) // 👈
def phi(f, g, h) = \x => g(f(x), h(x))

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بیایید نگاهی دقیق به دو مورد از آنها بیندازیم.

b ترکیبی است که همه ما می شناسیم. نتیجه تابع دوم را به تابع اول منتقل می کند. و psi دو مقدار را به تابع دوم ارسال می کند و سپس تابع اول را با هر دو نتیجه فراخوانی می کند.

بیایید دریابیم که آیا یک آرایه دوباره خاص است، اما توابع ترکیبی است

بیایید دوباره بررسی کنیم IsSpecial() اما با استفاده از “psi” این بار،

IEnumerable<(int First, int Second)> Pairs(int[] array)
=> array.Zip(array.Skip(1));

bool IsEven(int x) => x % 2 == 0;
bool NotEqual(bool x, bool y) => x != y;

// A more general signature would be:
// Func Psi(Func f, Func g)
// But to make things easier:
Func<int, int, bool> Psi(Func<bool, bool, bool> f, Func<int, bool> g)
// 👆👆
=> (x, y) => f(g(x), g(y));

var hasDifferentParity = Psi(NotEqual, IsEven); // 👈
bool IsSpecial(int[] array)
=> Pairs(array).All(pair => hasDifferentParity(pair.First, pair.Second));

// or
bool IsSpecial(int[] array)
=> Pairs(array).All(pair => Psi(NotEqual, IsEven)(pair.First, pair.Second));
// 👆👆

IsSpecial([1, 2, 3, 4]) // true
IsSpecial([1, 2, 4, 3]) // false

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به جای HasDifferentParity()، استفاده می کند Psi(NotEqual, IsEven).

و دوباره، در اینجا شبه کد psi آمده است: psi(f, g) = \x, y => f(g(x), g(y)).

Psi(NotEqual, IsEven) دو عدد صحیح دریافت می کند، تماس می گیرد IsEven با هر یک از آنها، و هر دو نتیجه را به NotEqual.

و voilà! این یک روش جدید از ترکیب است.

این یکی از صحبت‌هایی است که اگر می‌خواهید مفاهیم آن را درک کنید، چندین بار تکرار می‌شود، زیرا آنها چندان رایج نیستند. همچنین، همین مثال را در سایر زبان های کمتر شناخته شده که من حتی نام آنها را به خاطر ندارم، پوشش می دهد.

از آنجایی که احتمالاً از آن زبان‌های مبهم استفاده نخواهید کرد – من از آن استفاده نمی‌کنم، بخش ترکیب سخنرانی را یاد بگیرید. این ذهن دمیدن است.

با دوره 7 روزه رایگان ایمیل من، حرفه برنامه نویسی خود را اصلاح کنید. فقط در 7 ایمیل، بیش از 10 سال درس شغلی برای جلوگیری از اشتباهات شغلی پرهزینه دریافت خواهید کرد.

من در ابتدا نسخه توسعه یافته این پست را در وبلاگم قرار دادم.


ارسال نتیجه یک تابع به دیگری تنها راه برای ترکیب دو تابع نیست.

از کلاس های ریاضی، ما به نوشتن دو تابع مانند این عادت کرده ایم compose(f, g) = x => f(g(x)). اما به نظر می رسد راه های بیشتری وجود دارد.

این نکته اصلی من از سخنرانی “قدرت ترکیب عملکرد” ​​توسط Conor Hoekstra در کنفرانس NDC 2024 است. درصورتی‌که می‌خواهید تماشا کنید، ضبط YouTube اینجاست.

بحث نشان می‌دهد که چگونه می‌توان با استفاده از زبان‌هایی مانند پایتون، هسکل و سایر زبان‌های مبهم و باطنی، مشخص کرد که آیا یک آرایه خاص است یا نه.

اینها درسهایی هستند که من یاد گرفتم و چند نمونه کد را به سی شارپ ترجمه کردم.

یک راه حل ساده برای یافتن اینکه آیا یک آرایه خاص است یا خیر

بیایید دریابیم که آیا یک آرایه خاص است یا خیر.

یک آرایه خاص است اگر هر جفت عنصر متوالی شامل دو عدد با برابری متفاوت باشد. به عنوان مثال، [4,3,1,6] خاص نیست دارای سه جفت است: 4,3، 3,1، و 1,6. جفت دوم دارای دو عدد فرد است که باعث می شود آرایه ما “خاص” نباشد.

اگر می خواهید خودتان آن را امتحان کنید، مشکل LeetCode در اینجا وجود دارد.

و این راه حل من قبل از استفاده از هر یک از مفاهیم جدید سخنرانی است،

IEnumerable<(int First, int Second)> Pairs(int[] array)
{
    for (int i = 0; i < array.Length - 1; i++)
    {
        yield return (array[i], array[i + 1]);
    }
    // Or simply:
    // return array.Zip(array.Skip(1));
}

bool HasDifferentParity((int First, int Second) pair)
    => pair.First % 2 != pair.Second % 2;

bool IsSpecial(int[] array)
    => Pairs(array).All(HasDifferentParity);

IsSpecial([1, 2, 3, 4]) // true
IsSpecial([4, 3, 1, 6]) // false
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

استفاده می کند Pairs() برای تولید جفت عناصر متوالی، HasDifferentParity() برای پیدا کردن اینکه هر دو عدد در یک جفت زوج هستند یا فرد، و All() از LINQ. هیچ چیز فانتزی نیست!

به غیر از ترکیب “معمول”، روش های دیگری برای ترکیب توابع وجود دارد

در اینجا تعدادی از آنها به صورت شبه کد آورده شده است:

def i(x) = x
def k(x, y) = x
def ki(x, y) = y

def s(f, g) = \x => f(x, g(x))
def b(f, g) = \x => f(g(x)) // 👈

def c(f) = \x, y => f(y, x)
def w(f) = \x => f(x, x)

def d(f, g) = \x, y => f(x, g(y))
def b1(f, g) = \x, y => f(g(x, y))
def psi(f, g) = \x, y => f(g(x), g(y)) // 👈
def phi(f, g, h) = \x => g(f(x), h(x))
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

بیایید نگاهی دقیق به دو مورد از آنها بیندازیم.

b ترکیبی است که همه ما می شناسیم. نتیجه تابع دوم را به تابع اول منتقل می کند. و psi دو مقدار را به تابع دوم ارسال می کند و سپس تابع اول را با هر دو نتیجه فراخوانی می کند.

بیایید دریابیم که آیا یک آرایه دوباره خاص است، اما توابع ترکیبی است

بیایید دوباره بررسی کنیم IsSpecial() اما با استفاده از “psi” این بار،

IEnumerable<(int First, int Second)> Pairs(int[] array)
    => array.Zip(array.Skip(1));

bool IsEven(int x) => x % 2 == 0;
bool NotEqual(bool x, bool y) => x != y;

// A more general signature would be:
// Func Psi(Func f, Func g)
// But to make things easier:
Func<int, int, bool> Psi(Func<bool, bool, bool> f, Func<int, bool> g)
//                  👆👆
    => (x, y) => f(g(x), g(y));

var hasDifferentParity = Psi(NotEqual, IsEven); // 👈
bool IsSpecial(int[] array)
    => Pairs(array).All(pair => hasDifferentParity(pair.First, pair.Second));

// or
bool IsSpecial(int[] array)
    => Pairs(array).All(pair => Psi(NotEqual, IsEven)(pair.First, pair.Second));
    //                         👆👆

IsSpecial([1, 2, 3, 4]) // true
IsSpecial([1, 2, 4, 3]) // false
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

به جای HasDifferentParity()، استفاده می کند Psi(NotEqual, IsEven).

و دوباره، در اینجا شبه کد psi آمده است: psi(f, g) = \x, y => f(g(x), g(y)).

Psi(NotEqual, IsEven) دو عدد صحیح دریافت می کند، تماس می گیرد IsEven با هر یک از آنها، و هر دو نتیجه را به NotEqual.

و voilà! این یک روش جدید از ترکیب است.

این یکی از صحبت‌هایی است که اگر می‌خواهید مفاهیم آن را درک کنید، چندین بار تکرار می‌شود، زیرا آنها چندان رایج نیستند. همچنین، همین مثال را در سایر زبان های کمتر شناخته شده که من حتی نام آنها را به خاطر ندارم، پوشش می دهد.

از آنجایی که احتمالاً از آن زبان‌های مبهم استفاده نخواهید کرد – من از آن استفاده نمی‌کنم، بخش ترکیب سخنرانی را یاد بگیرید. این ذهن دمیدن است.


با دوره 7 روزه رایگان ایمیل من، حرفه برنامه نویسی خود را اصلاح کنید. فقط در 7 ایمیل، بیش از 10 سال درس شغلی برای جلوگیری از اشتباهات شغلی پرهزینه دریافت خواهید کرد.

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا