যে শিক্ষণ সমস্যায় আমি ঘাটাঘাটি করছি, আমি বুঝতে পেরেছিলাম যে আমার প্রয়োগ, রচনা ইত্যাদির জন্য ক্রিয়াকলাপগুলির জন্য টাইপক্লাসের প্রয়োজন আছে কারণগুলি ...
এটি কোনও ফাংশনের উপস্থাপনের সাথে আচরণ করা সুবিধাজনক হতে পারে যেমন এটি নিজেই ফাংশন, যাতে ফাংশনটি প্রয়োগ করে স্পষ্টভাবে কোনও দোভাষী ব্যবহার করে এবং ফাংশনগুলি রচনা করে একটি নতুন বিবরণ পাওয়া যায়।
একবার আপনার ফাংশনের জন্য টাইপক্লাস হয়ে গেলে, আপনি বিশেষ ধরণের ফাংশনগুলির জন্য টাইপক্লাস সংগ্রহ করতে পারেন - আমার ক্ষেত্রে, আমি ইনভারটিয়েবল ফাংশন চাই।
উদাহরণস্বরূপ, পূর্ণসংখ্যা অফসেটগুলি প্রয়োগ করে এমন ফাংশনগুলি কোনও পূর্ণসংখ্যাযুক্ত ADT দ্বারা প্রতিনিধিত্ব করা যেতে পারে। এই ফাংশনগুলি প্রয়োগ করার অর্থ কেবল পূর্ণসংখ্যা যুক্ত করা। মোড়ানো পূর্ণসংখ্যার যোগ করে রচনাটি প্রয়োগ করা হয়। বিপরীত ফাংশনটির পূর্ণসংখ্যা অবহেলিত থাকে। পরিচয় ফাংশন শূন্য মোড়ানো। ধ্রুবক ক্রিয়া সরবরাহ করা যায় না কারণ এর পক্ষে উপযুক্ত উপস্থাপনা নেই ation
অবশ্যই এটিগুলিকে বানান করার দরকার নেই যেমন এটির মানগুলি আসল হাস্কেল ফাংশন, তবে আমি একবার ধারণা পেয়েছিলাম, ভেবেছিলাম যে এর মতো একটি গ্রন্থাগার ইতিমধ্যে উপস্থিত থাকতে হবে এবং সম্ভবত স্ট্যান্ডার্ড বানানগুলি ব্যবহার করা উচিত। তবে আমি হাস্কেল লাইব্রেরিতে এ জাতীয় টাইপক্লাস খুঁজে পাই না।
আমি ডেটা ফাংশন মডিউলটি পেয়েছি , তবে টাইপক্লাস নেই - প্রিলিওড থেকে পাওয়া কিছু সাধারণ ফাংশন।
সুতরাং - কেন ফাংশন জন্য একটি টাইপক্লাস নেই? এটি "কেবল সেখানে নেই" বা "কারণ এটি আপনার মনে হয় তেমন দরকারী নয়"? অথবা ধারণাটি নিয়ে কোনও মৌলিক সমস্যা আছে?
এখন পর্যন্ত সবচেয়ে বড় সমস্যাটি আমি ভেবেছিলাম সবচেয়ে বড় সমস্যাটি হ'ল প্রকৃত ফাংশনগুলির উপর ফাংশন অ্যাপ্লিকেশনটি সম্ভবত একটি লুপিং সমস্যা এড়াতে সংকলক দ্বারা বিশেষ বিশেষায়িত হতে হবে - এই ফাংশনটি প্রয়োগ করার জন্য আমাকে ফাংশন অ্যাপ্লিকেশন ফাংশনটি প্রয়োগ করতে হবে, এবং এটি করার জন্য আমাকে ফাংশন অ্যাপ্লিকেশন ফাংশনটি কল করতে হবে এবং এটি করার জন্য ...
আরও ক্লু
আমি কী লক্ষ্য করছি তা দেখানোর জন্য উদাহরণ কোড ...
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
-- In my first version, Doable only had the one argument f. This version
-- seemed to be needed to support the UndoableOffset type.
--
-- It seems to work, but it also seems strange. In particular,
-- the composition function - a and b are in the class, but c isn't,
-- yet there's nothing special about c compared with a and b.
class Doable f a b where
fwdApply :: f a b -> a -> b
compDoable :: f b c -> f a b -> f a c
-- In the first version, I only needed a constraint for
-- Doable f a b, but either version makes sense.
class (Doable f a b, Doable f b a) => Undoable f a b where
bwd :: f a b -> f b a
bwdApply :: f a b -> b -> a
bwdApply f b = fwdApply (bwd f) b
-- Original ADT - just making sure I could wrap a pair of functions
-- and there were no really daft mistakes.
data UndoableFn a b = UFN { getFwd :: a -> b, getBwd :: b -> a }
instance Doable UndoableFn a b where
fwdApply = getFwd
compDoable f g = UFN ((getFwd f) . (getFwd g)) ((getBwd g) . (getBwd f))
instance Undoable UndoableFn a b where
bwd f = UFN (getBwd f) (getFwd f)
bwdApply = getBwd
-- Making this one work led to all the extensions. This representation
-- can only represent certain functions. I seem to need the typeclass
-- arguments, but also to need to restrict which cases can happen, hence
-- the GADT. A GADT with only one constructor still seems odd. Perhaps
-- surprisingly, this type isn't just a toy (except that the whole thing's
-- a toy really) - it's one real case I need for the exercise. Still a
-- simple special case though.
data UndoableOffset a b where
UOFF :: Int -> UndoableOffset Int Int
instance Doable UndoableOffset Int Int where
fwdApply (UOFF x) y = y+x
compDoable (UOFF x) (UOFF y) = UOFF (x+y)
instance Undoable UndoableOffset Int Int where
bwdApply (UOFF x) y = y-x
bwd (UOFF x) = UOFF (-x)
-- Some value-constructing functions
-- (-x) isn't shorthand for subtraction - whoops.
undoableAdd :: Int -> UndoableFn Int Int
undoableAdd x = UFN (+x) (\y -> y-x)
undoableMul :: Int -> UndoableFn Int Int
undoableMul x = UFN (*x) (`div` x)
-- With UndoableFn, it's possible to define an invertible function
-- that isn't invertible - to break the laws. To prevent that, need
-- the UFN constructor to be private (and all public ops to preserve
-- the laws). undoableMul is already not always invertible.
validate :: Undoable f a b => Eq a => f a b -> a -> Bool
validate f x = (bwdApply f (fwdApply f x)) == x
-- Validating a multiply-by-zero invertible function shows the flaw
-- in the validate-function plan. Must try harder.
main = do putStrLn . show $ validate (undoableAdd 3) 5
putStrLn . show $ validate (undoableMul 3) 5
--putStrLn . show $ validate (undoableMul 0) 5
fb1 <- return $ UOFF 5
fb2 <- return $ UOFF 7
fb3 <- return $ compDoable fb1 fb2
putStrLn $ "fwdApply fb1 3 = " ++ (show $ fwdApply fb1 3)
putStrLn $ "bwdApply fb1 8 = " ++ (show $ bwdApply fb1 8)
putStrLn $ "fwdApply fb3 2 = " ++ (show $ fwdApply fb3 2)
putStrLn $ "bwdApply fb3 14 = " ++ (show $ bwdApply fb3 14)
অ্যাপ্লিকেশনটিতে এক ধরণের একীকরণের সাথে জড়িত যেখানে একীভূত মানগুলি সমান নয়, তবে those অবিচ্ছিন্ন ফাংশনগুলির মাধ্যমে সম্পর্কিত - প্রোলোগ-স্টাইল যুক্তি নয় a = f(b)
বরং বরং সীমাবদ্ধতার সাথে a = b
। ইউনিয়ন-সন্ধানের কাঠামোটি অনুকূলকরণের ফলে বেশিরভাগ রচনাটির ফলাফল হবে। বিপরীতগুলির প্রয়োজনীয়তা সুস্পষ্ট হওয়া উচিত।
যদি কোনও ইউনিফাইড সেটে কোনও আইটেমের যথাযথ মান না থাকে তবে একটি নির্দিষ্ট আইটেম কেবল সেই ইউনিফাইড সেটটিতে অন্য আইটেমের তুলনায় পরিমাণমুক্ত হতে পারে। এজন্য আমি "রিয়েল" ফাংশনগুলি ব্যবহার করতে চাই না - those আপেক্ষিক মানগুলি গণনা করছি। আমি পুরো ফাংশনটির দিকটি ফেলে দিতে পারি এবং কেবল নিখুঁত এবং আপেক্ষিক পরিমাণ থাকতে পারি - আমার সম্ভবত কেবল সংখ্যা / ভেক্টর প্রয়োজন এবং (+)
- তবে আমার অভ্যন্তরের আর্কিটেকচার নভোচারী তার মজা চান।
আমি লিঙ্কগুলি আবার আলাদা করার একমাত্র উপায় ব্যাকট্র্যাকিংয়ের মাধ্যমে এবং সমস্ত কিছু খাঁটি - ইউনিয়ন- IntMap
ফাইন্ডটি "পয়েন্টার" হিসাবে কীগুলি ব্যবহার করে করা হবে । আমার সাধারণ ইউনিয়ন-সন্ধানের কাজ রয়েছে, তবে আমি এখনও অবিরত ফাংশনগুলি যোগ না করায় এটি এখানে তালিকাভুক্ত করার কোনও মানে নেই।
যে কারণে আমি আবেদনকারী, মোনাড, তীর ইত্যাদি ব্যবহার করতে পারি না
প্রধান ক্রিয়াকলাপগুলি আমি সরবরাহ করতে ফাংশন অ্যাবস্ট্রাকশন ক্লাসের প্রয়োজন তা হ'ল অ্যাপ্লিকেশন এবং রচনা। এটি পরিচিত শোনায় - যেমন Applicative
(<*>)
, Monad
(>>=)
এবং Arrow
(>>>)
সমস্ত রচনা ফাংশন। তবে, যে ধরণের ক্ষেত্রে আমার ক্ষেত্রে ফাংশন বিমূর্তি প্রয়োগ করে সেগুলিতে এমন কিছু ডেটা স্ট্রাকচার থাকবে যা কোনও ফাংশনকে উপস্থাপন করে তবে এটি কোনও ফাংশন (এবং ধারণ করতে পারে না) এবং যা কেবলমাত্র কিছু সীমিত ফাংশনের প্রতিনিধিত্ব করতে পারে।
আমি কোডটির ব্যাখ্যায় যেমন উল্লেখ করেছি, মাঝে মাঝে আমি কেবলমাত্র অন্যটির সাথে সম্পর্কিত একটি আইটেমের পরিমাণ নির্ধারণ করতে পারি কারণ "ইউনিফাইড" ক্লাস্টারের কোনও আইটেমের সঠিক মূল্য থাকে না। আমি সেই ফাংশনটির একটি উপস্থাপনা পেতে সক্ষম হতে চাই, যা সাধারণভাবে প্রদত্ত কয়েকটি ফাংশন (ইউনিয়নে একটি সাধারণ পূর্বপুরুষের কাছে চলে যাওয়া / গাছের সন্ধান করুন) এবং বেশ কয়েকটি বিপরীত ক্রিয়াকলাপের (অন্যটিতে ফিরে হাঁটতে হবে) গঠন করতে সক্ষম হতে চাই আইটেম)।
সাধারণ কেস - যেখানে মূল "ফাংশন" ইন্টিজার-অফসেট "ফাংশন" এর মধ্যে সীমাবদ্ধ রয়েছে, আমি সংহত ফলাফলটি একটি পূর্ণসংখ্যা-অফসেট "ফাংশন" হিসাবে চাই - উপাদান অফসেট যুক্ত করুন। এটি কেন অ্যাপ্লিকেশন ফাংশনের পাশাপাশি কমপোজিশন ফাংশনটি ক্লাসে থাকা প্রয়োজন তার একটি বড় অংশ।
এর অর্থ আমি ক্রিয়াকলাপগুলি সরবরাহ করতে পারি না pure
, return
বা arr
আমার প্রকারের জন্য তাই আমি ব্যবহার করতে পারি না Applicative
, Monad
বা Arrow
।
এটি এই ধরণের ব্যর্থতা নয় - এটি বিমূর্ততার মিল নয়। বিমূর্ততা আমি চাই একটি সাধারণ খাঁটি ফাংশন। কোনও পার্শ্ব-প্রতিক্রিয়া নেই, উদাহরণস্বরূপ, এবং সমস্ত ফাংশনের ক্ষেত্রে প্রমিত (।) এর সমতুল্য ব্যতীত অন্য ক্রিয়াকলাপগুলি সিকোয়েন্সিং এবং রচনা করার জন্য একটি সুবিধাজনক স্বরলিপি তৈরির প্রয়োজন নেই।
আমি উদাহরণস্বরূপ পারেCategory
। আমি নিশ্চিত যে আমার সমস্ত কার্যকরী জিনিস একটি পরিচয় দিতে সক্ষম হবে, যদিও আমার সম্ভবত এটির প্রয়োজন নেই। তবে Category
অ্যাপ্লিকেশন সমর্থন করে না, সেই ক্রিয়াকলাপটি যুক্ত করার জন্য আমার এখনও একটি উত্সযুক্ত শ্রেণীর প্রয়োজন।
Applicative
পুরোপুরি সঠিক বলে মনে করি না - এটির জন্য ক্রিয়াকলাপগুলির পাশাপাশি মানগুলি আবৃত করা দরকার, যেখানে আমি কেবল ফাংশনগুলি আবদ্ধ করতে চাই, এবং মোড়ানো ফাংশনগুলি সত্যই ফাংশন হয়, তবে আমার মোড়ানো ফাংশনগুলি সাধারণত হবে না (মধ্যে সর্বাধিক সাধারণ ক্ষেত্রে, তারা কার্যাদি বর্ণনা করে এএসটি)) যেখানে <*>
টাইপ আছে f (a -> b) -> f a -> f b
, আমি টাইপযুক্ত একটি অ্যাপ্লিকেশন অপারেটর চাই g a b -> a -> b
যেখানে a
এবং b
মোড়ানো ফাংশনটির ডোমেন এবং কোডোমাইন নির্দিষ্ট করুন, তবে মোড়কের অভ্যন্তরে যা রয়েছে তা আসল ফাংশন নয়। তীরগুলিতে - সম্ভবত, আমার একটি চেহারা হবে।