অসম্পূর্ণ হাস্কেল কোডটির এই টুকরা কীভাবে কাজ করে?


90

Https://en.uncyclopedia.co/wiki/Haskell পড়ার সময় (এবং সমস্ত "আপত্তিকর" জিনিস উপেক্ষা করে) আমি নিম্নলিখিত কোড অবলম্বন করে হোঁচট খেয়েছি:

fix$(<$>)<$>(:)<*>((<$>((:[{- thor's mother -}])<$>))(=<<)<$>(*)<$>(*2))$1

আমি যখন কোডটির এই অংশটি ghci(আমদানি করার পরে Data.Functionএবং Control.Applicative) চালনা করি তখন ghci2 এর সমস্ত শক্তির তালিকা মুদ্রণ করে।

এই টুকরা কোডটি কীভাবে কাজ করে?


4
আমি ভাবছি যে উত্তরটি হুব্রিস্টিকালি আপত্তিকর কিছু হতে পারে ... যদি সত্য হয়, তবে অশ্লীলতা এড়াতে আপনার প্রয়াসকে বিবেচনা করে ব্যঙ্গ করে।
মেরিডেথ

31
আপনি কি চেষ্টা করেছেন? স্পষ্টত চেষ্টা করার চেষ্টাগুলি হ'ল (ক) মন্তব্যটি সরান, (খ) কোডটি পুনরায় ফর্ম্যাট / পুনরায় প্রেরণ করা, (গ) ফান্টেক্টর / প্রয়োগকারী / মোনাডের কোন উদাহরণগুলি ব্যবহৃত হচ্ছে তা সম্ভবত কাজ (সম্ভবত সমস্ত তালিকা, তবে ধরে নিবেন না) .. … কোনও একক লাইনের কোডে মোনাডের পাঁচটি পৃথক দৃষ্টান্ত ব্যবহার করা থেকে যথেষ্ট ডিমান্ড প্রোগ্রামারকে কোনও কিছুই আটকাতে পারে না), (ঘ) আপনারা যতটা পারেন সহজ করুন। তারপরে আপনি কী রেখে গেছেন তা দেখুন।
dave4420

10
হাস্কেল এখন পর্যন্ত আমার প্রিয় প্রোগ্রামিংয়ের ভাষা, তবে তবুও আনসাইক্লোপিডিয়া.উইকিয়া / উইকি / হাস্কেল আমাকে এত হাসে!
অ্যান্ড্রুসি


4
কেউ যখন XYZ ভাষায় সন্ধান করতে পারে এমন অত্যন্ত কৃত্রিমভাবে ক্রিপ্টিক কোড টুকরোটি খুঁজে পায় তখন এটি আমাকে সত্যিই বিরক্ত করে এবং তখন দৃ fact়ভাবে দাবি করে যে "XYZ ভাষায় পাঠযোগ্য কোডটি লেখার পক্ষে কার্যত অসম্ভব"। তবে এটি কেবল আমি ...
ম্যাথমেটিক্যালআরচিড

উত্তর:


218

প্রথমত, আমাদের মনোরম সংজ্ঞা রয়েছে

x = 1 : map (2*) x

এটি নিজেই কিছুটা মনোমুগ্ধকর হয় যদি আপনি এটি আগে কখনও না দেখেন। যাইহোক এটি অলসতা এবং পুনরাবৃত্তিগুলির মোটামুটি মানক কৌশল। এখন, আমরা স্পষ্ট পুনরাবৃত্তি fixএবং পয়েন্ট-ফ্রি-ইফআই ব্যবহার করে মুক্তি পাব।

x = fix (\vs -> 1 : map (2*) vs)
x = fix ((1:) . map (2*))

পরবর্তী কাজটি আমরা যাচ্ছি সেটি হচ্ছে :বিভাগটি প্রসারিত করা এবং mapঅযথা জটিল করে তোলা।

x = fix ((:) 1 . (map . (*) . (*2)) 1)

ঠিক আছে, এখন আমাদের কাছে সেই ধ্রুবকের দুটি অনুলিপি রয়েছে 1। এটি কখনই করবে না, তাই আমরা পাঠক আবেদনকারীকে এটির নকল করতে ব্যবহার করব। এছাড়াও, ফাংশন রচনাটি কিছুটা আবর্জনা, সুতরাং আসুন (<$>)আমরা যেখানেই পারি সেখানে এটি প্রতিস্থাপন করুন ।

x = fix (liftA2 (.) (:) (map . (*) . (*2)) 1)
x = fix (((.) <$> (:) <*> (map . (*) . (*2))) 1)
x = fix (((<$>) <$> (:) <*> (map <$> (*) <$> (*2))) 1)

পরবর্তী: এই কলটি mapখুব বেশি পঠনযোগ্য। তবে ভয়ের কিছু নেই: আমরা মনড আইনটিকে আরও প্রসারিত করতে ব্যবহার করতে পারি। বিশেষত fmap f x = x >>= return . f, তাই

map f x = x >>= return . f
map f x = ((:[]) <$> f) =<< x

আমরা পয়েন্ট-ফ্রি-ইফাই করতে পারি, এর সাথে প্রতিস্থাপন (.)করতে পারি (<$>)এবং তারপরে কিছু উত্সাহী বিভাগ যুক্ত করতে পারি:

map = (=<<) . ((:[]) <$>)
map = (=<<) <$> ((:[]) <$>)
map = (<$> ((:[]) <$>)) (=<<)

আমাদের পূর্ববর্তী পদক্ষেপে এই সমীকরণটি প্রতিস্থাপন:

x = fix (((<$>) <$> (:) <*> ((<$> ((:[]) <$>)) (=<<) <$> (*) <$> (*2))) 1)

অবশেষে, আপনি আপনার স্পেসবারটি ভেঙে চমত্কার চূড়ান্ত সমীকরণ তৈরি করেন

x=fix(((<$>)<$>(:)<*>((<$>((:[])<$>))(=<<)<$>(*)<$>(*2)))1)

4
তুমি ছেড়ে গেছ {- thor's mother -}!
সাইমন শাইন

13

আমার আইআরসি লগগুলি সম্পূর্ণ চূড়ান্ত কোডের দিকে নিয়ে যাওয়া পরীক্ষাগুলির সম্পূর্ণ রান দিয়ে দীর্ঘ উত্তর লিখছিল (এটি ২০০৮ সালের শুরুর দিকে ছিল), তবে আমি দুর্ঘটনাক্রমে সমস্ত পাঠ্য :) যদিও খুব বেশি ক্ষতি হয় নি - ড্যানিয়েলের বিশ্লেষণ বেশিরভাগ অংশে রয়েছে।

আমি যা দিয়ে শুরু করেছি তা এখানে:

Jan 25 23:47:23 <olsner>        @pl let q = 2 : map (2*) q in q
Jan 25 23:47:23 <lambdabot>     fix ((2 :) . map (2 *))

পার্থক্যগুলি মূলত রিফ্যাক্টরিংগুলির ক্রমে নেমে আসে।

  • পরিবর্তে x = 1 : map (2*) xআমি শুরু করেছিলাম 2 : map ...এবং আমি প্রাথমিক 2 টি খুব শেষ সংস্করণ অবধি ঠিক রেখে দিয়েছি, যেখানে আমি একটিতে চেপে বসে প্রান্তটি (*2)পরিবর্তিত করেছি$2$1 । "মানচিত্রকে অযথা জটিল করুন" পদক্ষেপটি ঘটেনি (তাড়াতাড়ি)।
  • আমি লিফটএ 2 এর পরিবর্তে লিফটএম 2 ব্যবহার করেছি
  • অবরুদ্ধ map ফাংশনটি প্রয়োগমূলক সংযুক্তকারীগুলির সাথে লিফট এম 2 প্রতিস্থাপনের আগে স্থাপন করা হয়েছিল। সমস্ত স্পেস অদৃশ্য হয়ে যাওয়ার পরেও এটি।
  • এমনকি আমার "চূড়ান্ত" সংস্করণে .ফাংশন কম্পোজিশনের জন্য প্রচুর পরিমাণ ছিল । তাদের <$>সমস্তকে প্রতিস্থাপন করা সেই মাসের মধ্যে দৃশ্যমানভাবে ঘটেছিল যা অবিশ্বাস্যর মধ্যে ছিল।

বিটিডব্লিউ, এখানে একটি আপডেট সংস্করণ রয়েছে যা আর সংখ্যার উল্লেখ করে না 2:

fix$(<$>)<$>(:)<*>((<$>((:[{- Jörð -}])<$>))(=<<)<$>(*)<$>(>>=)(+)($))$1

10
প্রথম অনুচ্ছেদে "মুছে ফেলা" শব্দের বাদ দেওয়া কি ইচ্ছাকৃত? যদি তাই হয় তবে আমার টুপি আপনার কাছে স্যার।
জ্যাক ব্রাউনসন

4
@ জ্যাকব্রাউনসন এটি একটি সাধারণ ইন্টারনেট বুদ্ধিমান বিষয় , যদিও আমি নিশ্চিত না যে এটি উদ্দেশ্যমূলক ছিল কিনা।
লাম্বদা পরী

1

উভয় উত্তর নীল থেকে বর্ণিত সংক্ষিপ্ত মূল থেকে অপ্রচলিত কোড স্নিপেট প্রাপ্ত, কিন্তু প্রশ্নটি আসলে জিজ্ঞাসা করে যে দীর্ঘ অপ্রকাশিত কোডটি তার কাজটি কী করে?

এখানে কীভাবে:

fix$(<$>)<$>(:)<*>((<$>((:[{- thor's mother -}])<$>))(=<<)<$>(*)<$>(*2))$1 
= {- add spaces, remove comment -}
fix $ (<$>) <$> (:) <*> ( (<$> ((:[]) <$>) ) (=<<)  <$>  (*)  <$>  (*2) ) $ 1 
--                      \__\______________/_____________________________/
= {-    A   <$> B   <*> C                          $ x   =   A (B x) (C x) -}
fix $ (<$>) (1 :)     ( ( (<$> ((:[]) <$>) ) (=<<)  <$>  (*)  <$>  (*2) ) 1 )
--                      \__\______________/____________________________/
= {- op f g = (f `op` g) ; (`op` g) f = (f `op` g) -}
fix $ (1 :) <$>  ( (((=<<) <$> ((:[]) <$>) )        <$>  (*)  <$>  (*2) ) 1 )
--                  \\____________________/____________________________/
= {- <$> is left associative anyway -}
fix $ (1 :) <$>  ( ( (=<<) <$> ((:[]) <$>)          <$>  (*)  <$>  (*2) ) 1 )
--                  \__________________________________________________/
= {- A <$> foo = A . foo when foo is a function -}
fix $ (1 :) <$>  ( ( (=<<) <$> ((:[]) <$>)           .   (*)   .   (*2) ) 1 )
--                  \__________________________________________________/
= {- ((:[]) <$>) = (<$>) (:[]) = fmap (:[])  is a function -}
fix $ (1 :) <$>  ( ( (=<<)  .  ((:[]) <$>)           .   (*)   .   (*2) ) 1 )
--                  \__________________________________________________/
= {- (a . b . c . d) x = a (b (c (d x))) -}
fix $ (1 :) <$>      (=<<)  (  ((:[]) <$>)           (   (*)   (   (*2)   1 )))
= {- (`op` y) x = (x `op` y) -}
fix $ (1 :) <$>      (=<<)  (  ((:[]) <$>)           (   (*)   2             ))
= {- op x = (x `op`) -}
fix $ (1 :) <$>      (=<<)  (  ((:[]) <$>)              (2*)                  )
= {-  (f `op`) g = (f `op` g) -}
fix $ (1 :) <$>      (=<<)  (   (:[]) <$>               (2*)                  )
= {-  A <$> foo = A . foo when foo is a function -}
fix $ (1 :) <$>      (=<<)  (   (:[])  .                (2*)                  )
= {-  (f . g) = (\ x -> f (g x)) -}
fix $ (1 :) <$>      (=<<)  (\ x -> [2*x]  )
= {- op f = (f `op`)  -}
fix $ (1 :) <$>           ( (\ x -> [2*x]  )  =<<)

এখানে ( (\ x -> [2*x]) =<<) = (>>= (\ x -> [2*x])) = concatMap (\ x -> [2*x]) = map (2*)আবার একটি ফাংশন রয়েছে <$> = .:

= 
fix $ (1 :)  .  map (2*)
= {- substitute the definition of fix -}
let xs = (1 :) . map (2*) $ xs in xs
=
let xs = 1 : [ 2*x | x <- xs] in xs
= {- xs = 1 : ys -}
let ys =     [ 2*x | x <- 1:ys] in 1:ys
= {- ys = 2 : zs -}
let zs =     [ 2*x | x <- 2:zs] in 1:2:zs
= {- zs = 4 : ws -}
let ws =     [ 2*x | x <- 4:ws] in 1:2:4:ws
=
iterate (2*) 1
= 
[2^n | n <- [0..]]

ক্রমবর্ধমান ক্রমে 2 এর সমস্ত শক্তি ।


এটি ব্যবহার করে

  • A <$> B <*> C $ x = liftA2 A B C xএবং যেহেতু এটি একটি ফাংশন liftA2 A B Cপ্রয়োগ করা হয়, xএটি একটি ফাংশন হিসাবে এর অর্থ liftA2 A B C x = A (B x) (C x)
  • (f `op` g) = op f g = (f `op`) g = (`op` g) f অপারেটর বিভাগগুলির তিনটি আইন
  • >>=monadic বাইন্ড, এবং যেহেতু (`op` g) f = op f gএবং প্রকারগুলি হয়

    (>>=)                :: Monad m => m a -> (a -> m b ) -> m b
    (\ x -> [2*x])       :: Num t   =>         t -> [ t]
    (>>= (\ x -> [2*x])) :: Num t   => [ t]               -> [ t]
    

    প্রকারভেদ প্রয়োগ এবং প্রতিস্থাপনের মাধ্যমে আমরা দেখতে পাই যে প্রশ্নে মোনাড []যার জন্য (>>= g) = concatMap g

  • concatMap (\ x -> [2*x]) xs হিসাবে সরলীকৃত হয়

    concat $ map (\ x -> [2*x]) 
    =
    concat $ [ [2*x] | x <- xs]
    =
             [  2*x  | x <- xs]
    =
             map (\ x ->  2*x )
    
  • এবং সংজ্ঞা অনুসারে,

    (f . g) x  =  f (g x)
    
    fix f  =  let x = f x in x
    
    iterate f x  =  x : iterate f (f x)
                 =  x : let y = f x in 
                        y : iterate f (f y)
                 =  x : let y = f x in 
                        y : let z = f y in 
                            z : iterate f (f z)
                 = ...
                 = [ (f^n) x | n <- [0..]]
    

    কোথায়

            f^n  =  f  .  f  .  ...  . f
            --     \_____n_times _______/
    

    যাতে

    ((2*)^n) 1  =  ((2*) . (2*) .  ...  . (2*)) 1
                =    2*  (  2*  (  ...  (  2*   1 )...)) 
                =    2^n   ,  for n in [0..]
    
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.