হাসকেলে "উত্তোলন" কী?


138

"উত্তোলন" কী তা আমি বুঝতে পারি না। "লিফট" কী তা বোঝার আগে আমাকে প্রথমে মনডগুলি বুঝতে হবে? (আমি মোনাড সম্পর্কেও পুরোপুরি অজ্ঞ, :) বা কেউ আমাকে সহজ শব্দ দিয়ে এটি ব্যাখ্যা করতে পারে?


9
সম্ভবত দরকারী, নাও হতে পারে: haskell.org/haskellwiki/Lift
kennytm

উত্তর:


179

গাণিতিক ধারণার চেয়ে তুলনামূলক নকশার নকশা বেশি (যদিও আমি আশা করি কাছাকাছি কেউ এখন লিফটগুলি কীভাবে কোনও বিভাগ বা কিছু দেখিয়ে আমার খণ্ডন করবে)।

সাধারণত আপনার কাছে প্যারামিটারের সাথে কিছু ডেটা টাইপ থাকে। কিছুটা এইরকম

data Foo a = Foo { ...stuff here ...}

আপনাকে খুঁজে যে ব্যবহার অনেকটা ধরুন Foo(সাংখ্যিক ধরনের নেওয়া Int, Doubleইত্যাদি) এবং আপনি লিখতে কোডটি এই সংখ্যা unwraps, যোগ করে বা তাদের তা বৃদ্ধি পায়, এবং তারপর গোপন এগুলি ব্যাক আপ করা রাখা। আপনি আন-র্যাপ-ও-মোড়কের কোডটি একবার লিখে শর্ট সার্কিট করতে পারেন। এই ফাংশনটিকে traditionতিহ্যগতভাবে "লিফট" বলা হয় কারণ এটি দেখতে এরকম দেখাচ্ছে:

liftFoo2 :: (a -> b -> c) -> Foo a -> Foo b -> Foo c

অন্য কথায় আপনার একটি ফাংশন রয়েছে যা একটি দ্বি-আর্গুমেন্ট ফাংশন নেয় (যেমন (+)অপারেটর) এবং এটিকে ফুসের সমতুল্য ফাংশনে পরিণত করে।

সুতরাং এখন আপনি লিখতে পারেন

addFoo = liftFoo2 (+)

সম্পাদনা করুন: আরও তথ্য

আপনার অবশ্যই থাকতে পারে liftFoo3, liftFoo4ইত্যাদি। তবে এটি প্রায়শই প্রয়োজন হয় না।

পর্যবেক্ষণ দিয়ে শুরু করুন

liftFoo1 :: (a -> b) -> Foo a -> Foo b

তবে তা ঠিক তেমনই fmap। বরং liftFoo1আপনি লিখতে চেয়েছিলেন

instance Functor Foo where
   fmap f foo = ...

আপনি যদি সত্যিই সম্পূর্ণ নিয়মিততা চান তবে আপনি বলতে পারেন

liftFoo1 = fmap

আপনি যদি Fooকোনও ফান্টর তৈরি করতে পারেন তবে সম্ভবত আপনি এটি একটি প্রয়োগমূলক ফান্টর তৈরি করতে পারেন। আসলে, আপনি যদি লিখতে পারেন liftFoo2তবে আবেদনকারী উদাহরণটি দেখতে এরকম দেখাচ্ছে:

import Control.Applicative

instance Applicative Foo where
   pure x = Foo $ ...   -- Wrap 'x' inside a Foo.
   (<*>) = liftFoo2 ($)

(<*>)Foo এর জন্য অপারেটর টাইপ হয়েছে

(<*>) :: Foo (a -> b) -> Foo a -> Foo b

এটি মোড়ানো মানটির সাথে মোড়ক ফাংশনটি প্রয়োগ করে। সুতরাং আপনি যদি বাস্তবায়ন করতে পারেন liftFoo2তবে আপনি এটি এর নিরিখে এটি লিখতে পারেন। বা আপনি এটি সরাসরি বাস্তবায়ন করতে পারেন এবং এতে বিরক্ত করবেন না liftFoo2, কারণ Control.Applicativeমডিউলটি অন্তর্ভুক্ত রয়েছে

liftA2 :: Applicative f => (a -> b -> c) -> f a -> f b -> f c

এবং একইভাবে liftAএবং আছে liftA3। কিন্তু আপনি আসলে এগুলি খুব বেশি ব্যবহার করেন না কারণ অন্য অপারেটর রয়েছে

(<$>) = fmap

এটি আপনাকে লিখতে দেয়:

result = myFunction <$> arg1 <*> arg2 <*> arg3 <*> arg4

শব্দটি myFunction <$> arg1ফু-র মধ্যে আবৃত একটি নতুন ফাংশন দেয়। এটি পরিবর্তে পরবর্তী যুক্তিতে প্রয়োগ করা যেতে পারে (<*>)ইত্যাদি on সুতরাং এখন প্রতিটি আরটিটির জন্য একটি লিফট ফাংশন না করে আপনার কাছে কেবল আবেদনকারীদের একটি ডেইজি চেইন রয়েছে।


26
এটি সম্ভবত স্মরণ করিয়ে দেওয়ার মতো যে লিফ্টগুলির মানক আইনকে সম্মান করা উচিত lift id == idএবং lift (f . g) == (lift f) . (lift g)
কার্লোস স্কাইডেগার

13
লিফটগুলি প্রকৃতপক্ষে "একটি বিভাগ বা কিছু"। কার্লোস শুধু Functor আইন তালিকাভুক্ত, যেখানে হয়েছে idএবং .পরিচয় তীর তীর কিছু বিষয়শ্রেণীতে রচনা যথাক্রমে হয়। সাধারণত হাস্কেলের কথা বলার সময়, প্রশ্নে বিভাগটি "হাস্ক", যার তীরগুলি হ্যাস্কেল ফাংশন (অন্য কথায়, idএবং .আপনি জানেন এবং পছন্দ করেন এমন হাস্কেল ফাংশনগুলি উল্লেখ করুন)।
ড্যান বার্টন

3
এই পড়া উচিত instance Functor Foo, না instance Foo Functor? আমি নিজেকে সম্পাদনা করব তবে আমি 100% নিশ্চিত নই।
aMLoy

2
আবেদনকারী ছাড়াই উত্তোলন = ফ্যাক্টর ct আমি বলতে চাইছি আপনার কাছে দুটি পছন্দ রয়েছে: ফান্টেক্টর বা প্রয়োগমূলক ফান্টেক্টর। প্রথম লিফট একক পরামিতি দ্বিতীয় মাল্টি পরামিতি ফাংশন করে। খুব যে এটা। রাইট? এটি রকেট বিজ্ঞান নয় :) এটি কেবল শোনাচ্ছে। বিটিডব্লিউর উত্তরের জন্য ধন্যবাদ!
heেগেগাস

2
@ এটসি: এটি আংশিক প্রয়োগ। Wiki.haskell.org/ পার্টিশিয়াল_প্লিকেশন
পল জনসন

41

পল এবং ইয়ারছু উভয়ই ভাল ব্যাখ্যা।

আমি যুক্ত করতে চাই যে ফাংশনটি তুলে নেওয়া হচ্ছে তাতে একটি স্বেচ্ছাসেবী যুক্তি থাকতে পারে এবং তাদের একই ধরণের হতে হবে না। উদাহরণস্বরূপ, আপনি একটি লিফটফু 1 সংজ্ঞায়িত করতে পারেন:

liftFoo1 :: (a -> b) -> Foo a -> Foo b

সাধারণভাবে, 1 টি যুক্তিযুক্ত ফাংশনগুলির উত্তোলন টাইপ শ্রেণিতে ধরা পড়ে Functorএবং উত্তোলন অপারেশন বলা হয় fmap:

fmap :: Functor f => (a -> b) -> f a -> f b

liftFoo1এর ধরণের সাথে মিলটি নোট করুন । আসলে আপনার যদি থাকে তবে আপনি একটি উদাহরণ liftFoo1তৈরি করতে পারেন :FooFunctor

instance Functor Foo where
  fmap = liftFoo1

তদ্ব্যতীত, আর্গুমেন্ট একটি অবাধ নম্বরে তুলে সামান্যীকরণ বলা হয় আবেদন শৈলী । যতক্ষণ না আপনি নির্দিষ্ট সংখ্যক যুক্তি দিয়ে ফাংশনগুলির উত্তোলন উপলব্ধি না করেন ততক্ষণ এটিকে ডাইভিং করবেন না। তবে আপনি যখন করবেন, শিখুন একটি হাস্কেলের এ সম্পর্কে একটি ভাল অধ্যায় রয়েছে। Typeclassopedia বর্ণনা আরেকটি ভাল নথি Functor এবং আবেদন (পাশাপাশি অন্যান্য টাইপ শ্রেণীর; দস্তাবেজটি সঠিক অধ্যায় স্ক্রোল ডাউন)।

আশাকরি এটা সাহায্য করবে!


25

আসুন একটি উদাহরণ দিয়ে শুরু করা যাক (পরিষ্কার উপস্থাপনার জন্য কিছু সাদা স্থান যুক্ত করা হয়েছে):

> import Control.Applicative
> replicate 3 'a'
"aaa"
> :t replicate
replicate        ::         Int -> b -> [b]
> :t liftA2
liftA2 :: (Applicative f) => (a -> b -> c) -> (f a -> f b -> f c)
> :t liftA2 replicate
liftA2 replicate :: (Applicative f) =>       f Int -> f b -> f [b]
> (liftA2 replicate) [1,2,3] ['a','b','c']
["a","b","c","aa","bb","cc","aaa","bbb","ccc"]
> ['a','b','c']
"abc"

liftA2একটি ফাংশন প্লেইন ধরনের একটি ফাংশন রূপান্তরিত একই একটি আবৃত ধরনেরApplicative তালিকা, হিসাবে, IOইত্যাদি

আর একটি সাধারণ লিফট liftএসেছে Control.Monad.Trans। এটি একটি মোনাডের এক একাত্মক ক্রিয়াকে রূপান্তরিত মনাদের ক্রিয়ায় রূপান্তর করে।

সাধারণভাবে, "লিফট" কোনও ফাংশন / ক্রিয়াকে "মোড়ানো" প্রকারে উত্তোলন করে (যাতে মূল ফাংশনটি "মোড়কের নীচে" কাজ করে)।

এটি বোঝার সর্বোত্তম উপায় এবং মনডস ইত্যাদি, এবং কেন তারা কার্যকর তা বোঝার জন্য সম্ভবত এটি কোড করা এবং ব্যবহার করা। আপনি যদি আগে কোড করেছেন এমন কিছু যদি থাকে তবে আপনি সন্দেহ করেন যে এগুলি থেকে লাভবান হতে পারে (উদাহরণস্বরূপ এটি কোডটি সংক্ষিপ্ত করে তুলবে ইত্যাদি), কেবল এটি চেষ্টা করে দেখুন এবং আপনি সহজেই ধারণাটি উপলব্ধি করতে পারবেন।


13

উত্তোলন একটি ধারণা যা আপনাকে কোনও ফাংশনটিকে অন্য (সাধারণত আরও সাধারণ) সেটিংয়ের মধ্যে সম্পর্কিত ফাংশনে রূপান্তর করতে দেয়

http://haskell.org/haskellwiki/ লিফটিং এ একবার দেখুন


40
হ্যাঁ, তবে সেই পৃষ্ঠাটি শুরু হয় "আমরা সাধারণত একটি (সমকালীন) ফান্টেক্টর দিয়ে শুরু করি ..."। ঠিক নবাগত বন্ধুত্বপূর্ণ নয়।
পল জনসন

3
তবে "ফান্টেক্টর" লিঙ্কযুক্ত, সুতরাং নবাগত কেবল কোনও ফান্টেক্টর কী তা দেখতে ক্লিক করতে পারেন। স্বীকারোক্তিযুক্ত, লিঙ্কযুক্ত পৃষ্ঠাটি এত ভাল নয়। আমার একটি অ্যাকাউন্ট পেতে এবং এটি ঠিক করা দরকার।
jrockway

10
এটি অন্যান্য কার্যকরী প্রোগ্রামিং সাইটগুলিতে দেখেছি এমন একটি সমস্যা; নবাবী সম্পূর্ণ বৃত্ত (এবং বাঁকটি গোলাকার) না হওয়া পর্যন্ত প্রতিটি ধারণাটি অন্যান্য (অপরিচিত) ধারণার শর্তে ব্যাখ্যা করা হয়। পুনরাবৃত্তি পছন্দ সঙ্গে কিছু করতে হবে।
ডিএনএ

2
এই লিঙ্কের জন্য ভোট দিন। লিফট একটি বিশ্ব এবং অন্য একটি বিশ্বের মধ্যে সংযোগ তৈরি করে।
eccstartup

3
আপনি ইতিমধ্যে বিষয়টি বুঝতে পারলে এর মতো উত্তরগুলি কেবল তখনই ভাল।
ডাবলআর্ট

-2

এই চকচকে টিউটোরিয়াল অনুসারে , একটি ফান্টেক্টর হ'ল কিছু ধারক (যেমন Maybe<a>, List<a>বা Tree<a>এটি অন্য কোনও ধরণের উপাদান সংরক্ষণ করতে পারে a)। আমি <a>উপাদান ধরণের জন্য জাভা জেনেরিক সংকেত ব্যবহার করেছি aএবং উপাদানগুলিকে গাছের বেরি হিসাবে ভাবি Tree<a>। একটি ফাংশন রয়েছে fmap, যা একটি উপাদান রূপান্তর ফাংশন a->bএবং ধারক গ্রহণ করে functor<a>। এটি a->bকার্যকরভাবে এটিকে রূপান্তরিত করে ধারকটির প্রতিটি উপাদানকে প্রয়োগ করে functor<b>। যখন শুধুমাত্র প্রথম যুক্তি সরবরাহ করা হয়, a->b, fmapজন্য অপেক্ষা functor<a>। অর্থাত, a->bএকা সরবরাহ করা এই উপাদান-স্তরের ফাংশনটিকে functor<a> -> functor<b>পাত্রে সঞ্চালিত ফাংশনে রূপান্তরিত করে । এটিকে বলা হয় উত্তোলনফাংশন। কারণ ধারক এছাড়াও বলা হয় একটি functor , Functors বদলে Monads উত্তোলন জন্য একটি পূর্বশর্ত আছে। মনডা উত্তোলনের জন্য "সমান্তরাল" ধরণের। উভয়ই ফান্টেক্টর ধারণার উপর নির্ভর করে এবং করে f<a> -> f<b>। পার্থক্যটি হ'ল a->bলিফটিংটি রূপান্তরটির জন্য ব্যবহার করে যেখানে মোনাদকে ব্যবহারকারীর সংজ্ঞা দিতে হয় a -> f<b>


5
আমি আপনাকে নীচে একটি চিহ্ন দিয়েছি, কারণ "একটি ফান্টর কিছু ধারক" ট্রোল-স্বাদযুক্ত শিখা-টোপ। উদাহরণ: rকারওর কাছ থেকে এক ধরণের ফাংশন (আসুন cবিভিন্নতার জন্য ব্যবহার করুন ), হ'ল ফান্টেক্টর। তারা কোনও "থাকে না" c। এই উদাহরণে, fmap হ'ল ফাংশন রচনা, একটি a -> bফাংশন এবং একটি গ্রহণ করে r -> a, আপনাকে একটি নতুন, r -> bফাংশন দেয়। তবুও কোনও ধারক নেই A তবুও যদি আমি পারতাম তবে আমি চূড়ান্ত বাক্যটির জন্য এটি আবার চিহ্নিত করতাম।
বিএমফেফ

1
এছাড়াও, fmapএকটি ফাংশন, এবং কোনও কিছুর জন্য "অপেক্ষা" করে না; "পাত্র" একটি ফান্টেক্টর হ'ল উত্তোলনের পুরো পয়েন্ট । এছাড়াও, মনাদাস হ'ল, যদি কিছু থাকে তবে উত্তোলনের দ্বৈত ধারণা: একটি মোনাড আপনাকে এমন কিছু ব্যবহার করতে দেয় যা বেশ কয়েকটি ইতিবাচক সংখ্যক বার উঠিয়ে নেওয়া হয়েছে, যেন এটি কেবল একবার উত্তোলন করা হয়েছিল - এটি আরও চাটুকার হিসাবে পরিচিত ।
BMFh

1
@BMeph To wait, to expect, to anticipateপ্রতিশব্দের হয়। "ফাংশন অপেক্ষা করে" বলে আমার অর্থ "ফাংশন প্রত্যাশা"।
Val,

@ বিএমএফএফ আমি বলব যে ফান্টেক্টর কনটেইনার হয় এমন ধারণার প্রতিবিম্ব হিসাবে কোনও ফাংশন ভাবার পরিবর্তে, আপনাকে ফাংশনটির বুদ্ধিদীপ্ত ফ্যাক্টর উদাহরণটি ফাংশনগুলি ধারক নয় এমন ধারণার একটি প্রতিবিম্ব হিসাবে মনে করা উচিত। একটি ফাংশনটি একটি ডোমেন থেকে কোডোমেনে ম্যাপিং হয়, ডোমেনটি সমস্ত পরামিতিগুলির ক্রস পণ্য হয়, কোডোমেন ফাংশনের আউটপুট ধরণ being একইভাবে একটি তালিকা হ'ল ন্যাচারালস থেকে তালিকার অভ্যন্তরীণ ধরণের (ডোমেন -> কোডোমেন) ম্যাপিং। আপনি যদি ফাংশনটি স্মরণ করেন বা তালিকাটি না রাখেন তবে এগুলি আরও অনুরূপ হয়ে ওঠে।
সেমিকোলন

@ বিএমফে একমাত্র কারণের তালিকার মধ্যে একটি ধারক হিসাবে আরও বেশি ধারণা করা হয় যে অনেক ভাষায় এগুলিকে রূপান্তর করা যায়, যদিও traditionতিহ্যগতভাবে কার্য সম্পাদন করতে পারে না। তবে হাস্কেলের ক্ষেত্রেও এটি একটি যথাযথ বিবৃতি নয় কারণ উভয়কেই রূপান্তর করা যায় না এবং উভয়কেই অনুলিপি করা যেতে পারে: b = 5 : aএবং f 0 = 55 f n = g nউভয়ই "ধারক" কে সিউডো- মিউটেশন করার সাথে জড়িত। এছাড়াও তালিকাগুলি সাধারণত মেমরিতে সম্পূর্ণরূপে সঞ্চিত থাকে যখন কার্যকরীভাবে একটি গণনা হিসাবে সাধারণত সংরক্ষণ করা হয়। কিন্তু মেমোজাইজিং / মনরফিক তালিকাগুলি যেগুলি উভয়ের কলগুলির মধ্যে সংরক্ষণ করা হয় না সেই ধারণাটি ছড়িয়ে দেয়।
সেমিকোলন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.