আমি কীভাবে এই সি কোডের সাথে অ্যানালগ, হাস্কেল সূচক অনুসারে একটি তালিকা অ্যাক্সেস করতে পারি?
int a[] = { 34, 45, 56 };
return a[1];
উত্তর:
দেখুন এখানে ব্যবহৃত অপারেটর !!
।
আই [1,2,3]!!1
আপনাকে দেয় 2
, যেহেতু তালিকাগুলি 0-সূচীযুক্ত।
itemOf :: Int -> [a] -> Maybe a; x `itemOf` xs = let xslen = length xs in if ((abs x) > xslen) then Nothing else Just (xs !! (x `mod` xslen))
। দ্রষ্টব্য, এটি অসীম তালিকায় বিপর্যয়করভাবে ব্যর্থ হবে।
!!
এটি একটি আংশিক এবং এইভাবে অনিরাপদ ফাংশন। নিচে এবং ব্যবহার মন্তব্য কটাক্ষপাত lens
stackoverflow.com/a/23627631/2574719
আমি বলছি না যে আপনার প্রশ্ন বা প্রদত্ত উত্তরের সাথে কিছু ভুল আছে, তবে আপনি ভবিষ্যতে নিজের সময় বাঁচানোর জন্য এই গুগল যে দুর্দান্ত সরঞ্জামটি সম্পর্কে জানতে চান তা : Hoogle এর সাহায্যে আপনি স্ট্যান্ডার্ড লাইব্রেরি ফাংশন সন্ধান করতে পারেন এটি একটি প্রদত্ত স্বাক্ষরের সাথে মেলে। সুতরাং, সম্পর্কে কিছু না জেনে !!
, আপনার ক্ষেত্রে আপনি "এমন কিছু অনুসন্ধান করতে পারেন যা তরলাকারীদের Int
একটি তালিকা নেয় এবং একটি কিছু প্রদান করে", যথা
Int -> [a] -> a
লো এবং দেখুন , !!
প্রথম ফলাফল হিসাবে (যদিও টাইপ স্বাক্ষরটি আসলে আমরা অনুসন্ধান করেছি তার তুলনায় বিপরীতে দুটি যুক্তি রয়েছে)। ঝরঝরে, হাহ?
এছাড়াও, যদি আপনার কোড সূচকের উপর নির্ভর করে (তালিকার সামনে থেকে গ্রাস না করে), তালিকাগুলি আসলে সঠিক ডেটা কাঠামো নাও হতে পারে। ও (1) সূচক-ভিত্তিক অ্যাক্সেসের জন্য আরও দক্ষ বিকল্প রয়েছে যেমন অ্যারে বা ভেক্টর ।
ব্যবহারের বিকল্প (!!)
হ'ল
লেন্স প্যাকেজ এবং এর element
ফাংশন এবং সম্পর্কিত অপারেটরগুলি ব্যবহার করা।
লেন্স উপরে এবং তালিকা পরলোক কাঠামো ও নেস্টেড স্ট্রাকচার বিভিন্ন ধরণের ব্যবহার করার জন্য একটি অভিন্ন ইন্টারফেস প্রদান করে। নীচে আমি উদাহরণ সরবরাহে মনোনিবেশ করব এবং প্রকার স্বাক্ষর এবং লেন্স প্যাকেজের পিছনে তত্ত্ব উভয়কেই গ্লোস করব will
আপনি তত্ত্ব সম্পর্কে আরো জানতে চান একটি ভাল জায়গা শুরু করার জন্য এ রিডমি ফাইল GitHub রেপো ।
কমান্ড লাইনে:
$ cabal install lens
$ ghci
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
> import Control.Lens
ইনফিক্স অপারেটরের সাথে একটি তালিকা অ্যাক্সেস করতে
> [1,2,3,4,5] ^? element 2 -- 0 based indexing
Just 3
(!!)
সীমার বাইরে কোনও উপাদান অ্যাক্সেস করার সময় এটির বিপরীতে কোনও ব্যতিক্রম হবে না এবং এর Nothing
পরিবর্তে ফিরে আসবে । এটি প্রায়শই আংশিক ফাংশন এড়ানোর পরামর্শ দেওয়া হয় (!!)
বা head
যেহেতু তাদের আরও কোণার কেস থাকে এবং রান টাইম ত্রুটি হওয়ার সম্ভাবনা বেশি থাকে। এই উইকি পৃষ্ঠায় আংশিক কার্যকারিতা এড়ানোর জন্য আপনি আরও কিছুটা পড়তে পারেন ।
> [1,2,3] !! 9
*** Exception: Prelude.(!!): index too large
> [1,2,3] ^? element 9
Nothing
আপনি লেন্স কৌশলটি আংশিক ফাংশন হিসাবে বাধ্য করতে পারেন এবং (^?!)
অপারেটরের পরিবর্তে অপারেটরটি ব্যবহার করে সীমা ছাড়িয়ে গেলে একটি ব্যতিক্রম ছুঁড়ে ফেলতে পারেন (^?)
।
> [1,2,3] ^?! element 1
2
> [1,2,3] ^?! element 9
*** Exception: (^?!): empty Fold
এটি কেবল তালিকার মধ্যে সীমাবদ্ধ নয়। উদাহরণস্বরূপ, একই কৌশলটি স্ট্যান্ডার্ড পাত্রে প্যাকেজ থেকে গাছগুলিতে কাজ করে ।
> import Data.Tree
> :{
let
tree = Node 1 [
Node 2 [Node 4[], Node 5 []]
, Node 3 [Node 6 [], Node 7 []]
]
:}
> putStrLn . drawTree . fmap show $tree
1
|
+- 2
| |
| +- 4
| |
| `- 5
|
`- 3
|
+- 6
|
`- 7
আমরা এখন গভীরতার প্রথম ক্রমে গাছের উপাদানগুলি অ্যাক্সেস করতে পারি:
> tree ^? element 0
Just 1
> tree ^? element 1
Just 2
> tree ^? element 2
Just 4
> tree ^? element 3
Just 5
> tree ^? element 4
Just 3
> tree ^? element 5
Just 6
> tree ^? element 6
Just 7
আমরা পাত্রে প্যাকেজ থেকে ক্রমগুলি অ্যাক্সেস করতে পারি :
> import qualified Data.Sequence as Seq
> Seq.fromList [1,2,3,4] ^? element 3
Just 4
আমরা ভেক্টর প্যাকেজ থেকে স্ট্যান্ডার্ড ইন ইনডেক্সড অ্যারে , স্ট্যান্ডার্ড টেক্সট প্যাকেজ থেকে পাঠ্য , বাইটস্ট্রিংগুলি স্ট্যান্ডার্ড বাইট্রেস্টিং প্যাকেজ এবং অন্যান্য অনেকগুলি স্ট্যান্ডার্ড ডেটা স্ট্রাকচার অ্যাক্সেস করতে পারি । অ্যাক্সেসের এই স্ট্যান্ডার্ড পদ্ধতিটি আপনার ব্যক্তিগত ডেটা স্ট্রাকচারগুলিতে টাইপক্লাস ট্যারেবলযোগ্য উদাহরণ হিসাবে তৈরি করা যেতে পারে , লেন্স ডকুমেন্টেশনে ট্র্যাভারেবলের দীর্ঘতর উদাহরণ দেখুন । ।
নেস্টেড কাঠামোর মধ্যে নিচে খনন লেন্স সঙ্গে সহজ hackage । উদাহরণস্বরূপ তালিকার তালিকায় একটি উপাদান অ্যাক্সেস করা:
> [[1,2,3],[4,5,6]] ^? element 0 . element 1
Just 2
> [[1,2,3],[4,5,6]] ^? element 1 . element 2
Just 6
নেস্টেড ডেটা স্ট্রাকচার বিভিন্ন ধরণের থাকলেও এই রচনাটি কাজ করে। সুতরাং উদাহরণস্বরূপ যদি আমার কাছে গাছগুলির একটি তালিকা থাকে:
> :{
let
tree = Node 1 [
Node 2 []
, Node 3 []
]
:}
> putStrLn . drawTree . fmap show $ tree
1
|
+- 2
|
`- 3
> :{
let
listOfTrees = [ tree
, fmap (*2) tree -- All tree elements times 2
, fmap (*3) tree -- All tree elements times 3
]
:}
> listOfTrees ^? element 1 . element 0
Just 2
> listOfTrees ^? element 1 . element 1
Just 4
যতক্ষণ না তারা Traversable
প্রয়োজনীয়তা পূরণ করে স্বেচ্ছাচারিতামূলক প্রকারের সাথে আপনি গভীরভাবে বাসা বাঁধতে পারেন । সুতরাং পাঠ্যের ক্রমগুলির গাছগুলির একটি তালিকা অ্যাক্সেস করা কোনও ঘাম নয়।
অনেক ভাষায় একটি সাধারণ ক্রিয়াকলাপ হ'ল একটি অ্যারেতে সূচিযুক্ত অবস্থান নির্ধারণ করা। অজগর আপনি সম্ভবত:
>>> a = [1,2,3,4,5]
>>> a[3] = 9
>>> a
[1, 2, 3, 9, 5]
লেন্স প্যাকেজের সাথে এই কার্যকারিতা দেয় (.~)
অপারেটর। যদিও অজগর থেকে পৃথক মূল তালিকাটি পরিবর্তিত হয় না, বরং একটি নতুন তালিকা ফিরে আসে।
> let a = [1,2,3,4,5]
> a & element 3 .~ 9
[1,2,3,9,5]
> a
[1,2,3,4,5]
element 3 .~ 9
কেবল একটি ফাংশন এবং (&)
অপারেটর, লেন্স প্যাকেজের অংশ
, কেবল বিপরীত ফাংশন অ্যাপ্লিকেশন। এখানে এটি আরও সাধারণ ফাংশন অ্যাপ্লিকেশন সহ।
> (element 3 .~ 9) [1,2,3,4,5]
[1,2,3,9,5]
নির্ধারিত কাজগুলি পুনরায় নির্বিচারে বাসা বাঁধার সাথে পুরোপুরি সূক্ষ্মভাবে কাজ করে Traversable
।
> [[1,2,3],[4,5,6]] & element 0 . element 1 .~ 9
[[1,9,3],[4,5,6]]
Data.Traversable
কি পুনরায় রফতানির চেয়ে লিঙ্ক যুক্ত করতে পারি lens
?
সরাসরি উত্তর ইতিমধ্যে দেওয়া হয়েছিল: ব্যবহার করুন !!
।
তবে newbies প্রায়শই এই অপারেটরকে অতিরিক্ত ব্যবহার করার প্রবণতা দেখায় যা হাস্কেলের জন্য ব্যয়বহুল (কারণ আপনি একক লিঙ্কযুক্ত তালিকায় কাজ করেন, অ্যারেগুলিতে নয়)। এটি এড়াতে বেশ কয়েকটি দরকারী কৌশল রয়েছে, সবচেয়ে সহজতমটি জিপটি ব্যবহার করে। আপনি যদি লিখেন তবে আপনি zip ["foo","bar","baz"] [0..]
প্রতিটি জোড়ের প্রতিটি উপাদানের সাথে সূচকগুলি "সংযুক্ত" সহ একটি নতুন তালিকা পাবেন: [("foo",0),("bar",1),("baz",2)]
যা প্রায়শই আপনার প্রয়োজন মতো হয়।
হাস্কেলের স্ট্যান্ডার্ড তালিকার ডেটা টাইপ forall t. [t]
বাস্তবায়নের ক্ষেত্রে সি লিঙ্কিত তালিকার সাথে সাদৃশ্যপূর্ণ এবং এর প্রয়োজনীয় বৈশিষ্ট্যগুলি ভাগ করে। লিঙ্কযুক্ত তালিকাগুলি অ্যারে থেকে খুব আলাদা। সর্বাধিক উল্লেখযোগ্যভাবে, সূচকের মাধ্যমে অ্যাক্সেস হ'ল একটি ও (1) লিনিয়ার-, ও (1) ধ্রুবক-সময় অপারেশনের পরিবর্তে।
আপনার যদি ঘন ঘন এলোমেলো অ্যাক্সেসের প্রয়োজন হয় তবে Data.Array
মানটি বিবেচনা করুন ।
!!
সীমার বাইরে সূচকগুলির জন্য ক্র্যাশকে উস্কে দেওয়া একটি অনিরাপদ আংশিক সংজ্ঞায়িত ফাংশন। জেনে রাখুন যে মান গ্রন্থাগার কিছু যেমন আংশিক ফাংশন (ধারণ করা head
, last
ইত্যাদি)। সুরক্ষার জন্য, একটি বিকল্প ধরণ Maybe
বা Safe
মডিউল ব্যবহার করুন।
যুক্তিসঙ্গতভাবে দক্ষ, শক্তসমর্থ মোট (সূচকগুলির জন্য ≥ 0) সূচীকরণ কার্যের উদাহরণ:
data Maybe a = Nothing | Just a
lookup :: Int -> [a] -> Maybe a
lookup _ [] = Nothing
lookup 0 (x : _) = Just x
lookup i (_ : xs) = lookup (i - 1) xs
লিঙ্কযুক্ত তালিকার সাথে কাজ করা, প্রায়শই অর্ডিনালগুলি সুবিধাজনক:
nth :: Int -> [a] -> Maybe a
nth _ [] = Nothing
nth 1 (x : _) = Just x
nth n (_ : xs) = nth (n - 1) xs
[1,2,3]!!6
আপনাকে একটি রানটাইম ত্রুটি দেবে।!!
টাইপটি থাকলে খুব সহজেই এড়ানো যেত[a] -> Int -> Maybe a
। আমাদের হাস্কেল হওয়ার খুব কারণ হ'ল এই ধরনের রানটাইম ত্রুটিগুলি এড়ানো!