জাভা 8 এ 2 তীরযুক্ত ল্যাম্বডা বলতে কী বোঝায়?


118

আমি এর আগে বেশ কয়েকটি জাভা 8 টি টিউটোরিয়াল পড়েছি।

এই মুহুর্তে আমি নিম্নলিখিত বিষয়টির মুখোমুখি হয়েছি: জাভা কি কারিঙ সমর্থন করে?

এখানে, আমি নিম্নলিখিত কোড দেখতে পাচ্ছি:

IntFunction<IntUnaryOperator> curriedAdd = a -> b -> a + b;
System.out.println(curriedAdd.apply(1).applyAsInt(12));

আমি বুঝতে পারি যে এই উদাহরণটি 2 টি উপাদানের যোগফল কিন্তু আমি নির্মাণটি বুঝতে পারি না:

a -> b -> a + b;

ভাবের বাম অংশ অনুসারে, এই সারিটি নিম্নলিখিত ফাংশনটি প্রয়োগ করবে:

R apply(int value); 

এর আগে, আমি কেবল একটি তীর দিয়ে ল্যাম্বডাসের সাথে দেখা করেছি।


6
তরকারী বলতে কী বোঝ? এটি এই প্রশ্নের বেশ অবিচ্ছেদ্য।
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

12
এটি কেবল একটি ল্যাম্বডা যা একটি ল্যাম্বদা ফেরত দেয়।
ইলমারি করোনেন

উত্তর:


118

আপনি যদি এটি অ-শর্টহ্যান্ড ল্যাম্বদা সিনট্যাক্স বা প্রাক-ল্যাম্বদা জাভা বেনাম শ্রেণীর সিনট্যাক্স হিসাবে প্রকাশ করেন তবে কী ঘটছে তা পরিষ্কার হয়ে যায় ...

মূল প্রশ্ন। দুটি তীর কেন? সরল, দুটি ফাংশন সংজ্ঞায়িত করা হচ্ছে ... প্রথম ফাংশনটি একটি ফাংশন-সংজ্ঞায়িত-ফাংশন, দ্বিতীয়টি সেই ফাংশনের ফলাফল, যা ফাংশন হিসাবেও ঘটে to প্রতিটি প্রয়োজন একটি-> সংজ্ঞা দেওয়ার অপারেটর ।

অ সাধারণভাবে সংক্ষেপে

IntFunction<IntUnaryOperator> curriedAdd = (a) -> {
    return (b) -> {
        return a + b;
    };
};

জাভা 8 এর আগে প্রাক-লাম্বদা

IntFunction<IntUnaryOperator> curriedAdd = new IntFunction<IntUnaryOperator>() {
    @Override
    public IntUnaryOperator apply(final int value) {
        IntUnaryOperator op = new IntUnaryOperator() {
            @Override
            public int applyAsInt(int operand) {
                return operand + value;
            }
        };
        return op;
    }
};

1
প্রাক-ল্যাম্বডায় final int value
njzk2

8
হ্যাঁ, আপনি সঠিক, তবে আমি লিখেছি যে এখনও একটি জাভা 8 সংকলক ব্যবহার করছে যা আপনাকে "কার্যকরভাবে চূড়ান্ত" জিনিসগুলি ব্যবহার করতে দেয়
অ্যাডাম

1
@ জিস্ট্যাকওভারফ্লো হ্যাঁ, তবে জাভা 8 হয় নাpre-lambda
njzk2

1
আপনি জাভা 8-এ প্রাক-ল্যাম্বদা স্টাইল ব্যবহার করতে পারেন। আমি এটি লিখেছি
JFY

3
লম্বডাসটি কি কেবল তাই করা হয়নি যাতে লোকেরা পয়েন্ট করতে পারে? :-)
স্টিফেন

48

আন IntFunction<R>একটি ফাংশন int -> R। আন IntUnaryOperatorএকটি ফাংশন int -> int

সুতরাং এটি একটি IntFunction<IntUnaryOperator>এমন একটি ফাংশন যা একটি intপ্যারামিটার হিসাবে নেয় এবং একটি ফাংশন দেয় যা একটি intপ্যারামিটার হিসাবে নেয় এবং একটি ফেরত দেয় int

a -> b -> a + b;
^    |         |
|     ---------
|         ^
|         |
|         The IntUnaryOperator (that takes an int, b) and return an int (the sum of a and b)
|
The parameter you give to the IntFunction

যদি আপনি ল্যাম্বডাকে "পচন" করতে বেনাম শ্রেণি ব্যবহার করেন তবে এটি আরও পরিষ্কার is

IntFunction<IntUnaryOperator> add = new IntFunction<IntUnaryOperator>() {
    @Override
    public IntUnaryOperator apply(int a) {
        return new IntUnaryOperator() {
            @Override
            public int applyAsInt(int b) {
                return a + b;
            }
        };
    }
};

29

বন্ধনী যুক্ত করা এটি আরও স্পষ্ট করতে পারে:

IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));

অথবা সম্ভবত মধ্যবর্তী ভেরিয়েবল সাহায্য করতে পারে:

IntFunction<IntUnaryOperator> curriedAdd = a -> {
    IntUnaryOperator op = b -> a + b;
    return op;
};

24

আসুন আরও স্পষ্ট করার জন্য ল্যাম্বডা এক্সপ্রেশনটি প্রথম বন্ধনীর সাথে আবার লিখি:

IntFunction<IntUnaryOperator> curriedAdd = a -> (b -> (a + b));

সুতরাং আমরা একটি ফাংশন ঘোষণা করছি intযা গ্রহণ করে একটি Function। আরও সুনির্দিষ্টভাবে, ফাংশনটি ফিরে আসে intএবং একটি int(দুটি উপাদানের যোগফল) দেয়: এটি হিসাবে একটি হিসাবে উপস্থাপিত হতে পারে IntUnaryOperator

সুতরাং, curriedAddএকটি ফাংশন একটি গ্রহণ intএবং একটি ফেরত IntUnaryOperator, তাই এটি হিসাবে প্রতিনিধিত্ব করা যেতে পারে IntFunction<IntUnaryOperator>


9

এটি দুটি ল্যাম্বডা এক্সপ্রেশন।

IntFunction<IntUnaryOperator> curriedAdd = 
  a -> { //this is for the fixed value
    return b -> { //this is for the add operation
      return a + b;
    };
  }

IntUnaryOperator addTwo = curriedAdd.apply(2);
System.out.println(addTwo.applyAsInt(12)); //prints 14

8

আপনি যদি IntFunctionএটি তাকান এটি আরও পরিষ্কার হতে পারে: IntFunction<R>একটি FunctionalInterface। এটি এমন একটি ফাংশন উপস্থাপন করে যা গ্রহণ করে intএবং প্রকারের মান দেয় R

এই ক্ষেত্রে, রিটার্নের ধরণটিও Rএকটি FunctionalInterface, যথা একটি IntUnaryOperator। সুতরাং প্রথম (বহিরাগত) ফাংশনটি নিজেই একটি ফাংশন দেয়।

এই ক্ষেত্রে: যখন একটি প্রয়োগ করা হয় int, curriedAddএমন একটি ফাংশন ফেরত আসবে যা আবার একটি গ্রহণ করে int(এবং আবার ফিরে আসে int, কারণ এটি that'sIntUnaryOperator ঘটে)।

ফাংশনাল প্রোগ্রামিংয়ে কোনও ফাংশনের প্রকারটি লিখতে সাধারণ param -> return_valueএবং আপনি এখানে ঠিক এটি দেখতে পান। সুতরাং ধরণ curriedAddহয় int -> int -> int(অথবা int -> (int -> int)যদি আপনি যে ভাল মতো)।

জাভা 8 এর ল্যাম্বদা সিনট্যাক্স এটির সাথে চলে। যেমন একটি ফাংশন সংজ্ঞায়িত করতে, আপনি লিখুন

a -> b -> a + b

যা প্রকৃত ল্যাম্বডা ক্যালকুলাসের সাথে খুব মিল:

λa λb a + b

λb a + bএমন একটি ফাংশন যা একটি একক প্যারামিটার নেয় bএবং একটি মান (যোগফল) দেয়। λa λb a + bএকটি ফাংশন যা একটি একক প্যারামিটার গ্রহণ করে এবং একটি একক প্যারামিটারের aঅন্য ফাংশন প্রদান করে। λa λb a + bআয় λb a + bসঙ্গে aপ্যারামিটার মান নির্ধারণ করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.