কীভাবে অলস ক্রমটি ক্লোজুরে নন-অলসে রূপান্তর করবেন


95

আমি ক্লোজুরেতে নিম্নলিখিতগুলি চেষ্টা করেছিলাম, একটি অ-অলস ক্রমের ক্লাসটি ফিরে আসার প্রত্যাশায়:

(.getClass (doall (take 3 (repeatedly rand))))

তবে এটি এখনও ফিরে আসে clojure.lang.LazySeq। আমার অনুমান যা doallপুরো ক্রমটি মূল্যায়ন করে তবে এটি মেমোজাইজেশনের জন্য এখনও কার্যকর হিসাবে এটি মূল ক্রমটি ফেরত দেয়।

সুতরাং একটি অলস একটি অলস ক্রম তৈরি করার মূর্তিাত্মক উপায় কি?


আমি আশ্চর্য হয়েছি কেউ কেন জিজ্ঞাসা করেনি যে আপনি কেন doall
টার-

আপনি কোনও ভেক্টরে রূপান্তর করতে পারেন:(vec (take 3 (repeatedly rand)))
ক্রিস

উত্তর:


161

doallআপনার যা দরকার তা হল। শুধু কারণ seqটাইপ হয়েছে LazySeqমানে এই নয় এটা মূল্যায়ন পাওয়ার অপেক্ষায় রয়েছে। অলস seqতাদের ফলাফলগুলি ক্যাশে করে, তাই আপনার সমস্ত কিছু জোর করার জন্য আপনাকে seqএকবার অলসভাবে হাঁটতে হবে (এবং যেমন করা doallহয়) এবং এটি অ-অলসভাবে রেন্ডার করে। পুরো সংগ্রহটি মূল্যায়ন করতে বাধ্য seqকরে না


4
আমি এটি গ্রহণযোগ্য উত্তরে পরিবর্তন করেছি। সম্পর্কিত নোটে, কোনও অলসেক আগে মূল্যায়ন করা হয়েছে কিনা তা আপনি কোন উপায়ে নির্ধারণ করতে পারেন?
টিম ক্লেমনস

10
আমি বিশ্বাস করি আপনি কেবল কল করেছেন realized?
toofarsideways

4
realizeম্যাচ করার জন্য সম্ভবত কোনও অপারেশন হওয়া উচিত realized?
রিউত শরবানী

এই সব খুব সুন্দর। তবে যেহেতু কিছু ক্রিয়াকলাপ contains?আপনি অলস সিককে বুঝতে পেরেছেন কিনা তা বিবেচনা করে না, সুতরাং নির্দিষ্ট প্রশ্নের উত্তর হিসাবে জিজ্ঞাসা করা হয়েছে, তবে প্রশ্নের শিরোনামের চেয়ে কম less
ম্যাটানস্টার

75

এটি কিছুটা হারে ট্যাক্সোনমি নিয়ে প্রশ্ন। একটি অলস ক্রম কেবল একটি ধরণের ক্রম যেমন একটি তালিকা, ভেক্টর বা মানচিত্র। সুতরাং উত্তর অবশ্যই "এটি কী ধরণের অলস ক্রম আপনি পেতে চান তার উপর নির্ভর করে:
আপনার চয়ন থেকে নিন:

  • একটি প্রাক্তন অলস (সম্পূর্ণ মূল্যায়ন) অলস ক্রম (doall ... )
  • অনুক্রমিক অ্যাক্সেসের জন্য একটি তালিকা (apply list (my-lazy-seq)) OR (into () ...)
  • পরে এলোমেলো অ্যাক্সেসের জন্য একটি ভেক্টর (vec (my-lazy-seq))
  • আপনার কোনও বিশেষ উদ্দেশ্য থাকলে মানচিত্র বা একটি সেট।

আপনার স্যুটগুলির মধ্যে স্যুটগুলির যে কোনও ধরণের সিকোয়েন্স থাকতে পারে।


এটি সেরা উত্তর।
ফিলিপ

4
গৃহীত উত্তরটি প্রযুক্তিগতভাবে সঠিক, তবে এই উত্তরটি আমার পক্ষে সবচেয়ে কার্যকর ছিল। আমি কোনও ভেক্টরের উপরে একটি ফাংশন মানচিত্রের চেষ্টা করছিলাম এবং তারপরে ফলাফলটি কোনও ফাইলে থুথু দিয়েছি, এবং ডোল কল করার পরেও এই ফাইলটিতে ক্রমের সামগ্রীর পরিবর্তে "Clojure.lang.LazySeq@address" রয়েছে। ভ্যালু মানচিত্রে কল করে ভ্যাক্ট ফিরিয়ে দেওয়া আমার কাছে ফাইলটিতে থুথু দেওয়ার দরকার ছিল।
জেসি রোজালিয়া

4
@ জেসারোসালিয়া এটি জেনে রাখা ভাল যে এসও এর মধ্যে একমাত্র এবং কেবল রিচ হিকির প্রতিক্রিয়া প্রযুক্তিগতভাবে সঠিক ছিল। ;-)
ফিল

(vec (my-lazy-seq))নিচের মত পরিস্থিতিতে এত সুন্দর নয়: (vec (json/parse-string "{\"foo\":\"bar\"}")) ;; => [["foo" "bar"]]যেহেতু cheshireমনোনীত করেন একটি অলস-SeQ উত্পাদন করতে(json/parse-string)
codeasone

উপরের জন্য (json/parse-string-strict)
প্রশমনটি

22

এই ধনী লোকটি তার ক্লোজারটি জানে এবং একেবারে ঠিক।
বুথ আমি মনে করি এই কোড-স্নিপেট, আপনার উদাহরণ ব্যবহার করে, এই প্রশ্নের কার্যকর সহায়ক হতে পারে:

=> (realized? (take 3 (repeatedly rand))) 
false
=> (realized? (doall (take 3 (repeatedly rand)))) 
true

প্রকৃতপক্ষে টাইপ পরিবর্তন হয়নি তবে উপলব্ধি আছে


4
তবে এটি লক্ষণীয় যে আপনাকে realized?ফিরে আসার জন্য পুরো ক্রমটি জোর করতে হবে না true। উদা(let [r (range) r? (realized? r)] (doall (take 1 r)) [r? (realized? r)]) => [false true]
অ্যালেক্স কভেন্ট্রি

22
এই ধনী লোক: ডি হা হা
জুলিয়ান ক্রিস্পেল-স্যামসেল

10
@ নিমরোড :) এই শ্লোকটি "হস ক্লোজার" এ বোঝানো হয়েছিল।
পিটার

10
যারা জানেন না তাদের জন্য, "ধনী লোক" ক্লোজুরে আবিষ্কার করেছিল।
এর্টুরনে

4
@ অ্যালেক্সকভেন্ট্রি আপনার উদাহরণটি প্রত্যাবর্তন করবে[true true]

7

পুনরাবৃত্তি না হওয়ার বিষয়ে এই ব্লগ পোস্টটিতে আমি হোঁচট doallখেয়েছি। তার জন্য আমি পোস্টটিতে প্রথম মন্তব্যটি পেয়েছি কৌশলটি। এর লাইন ধরে কিছু:

(use 'closure.walk)
(postwalk identity nested-lazy-thing)

আমি এটি একটি ইউনিট পরীক্ষায় দরকারী দেখতে পেয়েছি যেখানে আমি mapত্রুটি শর্তটি জোর করার জন্য কিছু নেস্টেড অ্যাপ্লিকেশনগুলির মূল্যায়ন করতে বাধ্য করতে চেয়েছিলাম ।


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