আমি বর্তমানে একটি প্রোগ্রামিং ভাষার জন্য একটি সাধারণ দোভাষী নিয়ে কাজ করছি এবং আমার কাছে এই জাতীয় ডেটা টাইপ রয়েছে:
data Expr
= Variable String
| Number Int
| Add [Expr]
| Sub Expr Expr
এবং আমার অনেকগুলি ফাংশন রয়েছে যা সাধারণ জিনিসগুলি করে:
-- Substitute a value for a variable
substituteName :: String -> Int -> Expr -> Expr
substituteName name newValue = go
where
go (Variable x)
| x == name = Number newValue
go (Add xs) =
Add $ map go xs
go (Sub x y) =
Sub (go x) (go y)
go other = other
-- Replace subtraction with a constant with addition by a negative number
replaceSubWithAdd :: Expr -> Expr
replaceSubWithAdd = go
where
go (Sub x (Number y)) =
Add [go x, Number (-y)]
go (Add xs) =
Add $ map go xs
go (Sub x y) =
Sub (go x) (go y)
go other = other
কিন্তু এই ফাংশনগুলির প্রত্যেকটিতে, আমাকে সেই অংশটি পুনরাবৃত্তি করতে হবে যা ফাংশনের একটি অংশে সামান্য পরিবর্তন করে কোডটিকে পুনরাবৃত্তভাবে ডাকে calls আরও সাধারণভাবে এটি করার কোনও বিদ্যমান উপায় আছে কি? আমাকে বরং এই অংশটি অনুলিপি করতে হবে না:
go (Add xs) =
Add $ map go xs
go (Sub x y) =
Sub (go x) (go y)
go other = other
এবং প্রতিবার কেবল একটি একক কেস পরিবর্তন করুন কারণ এ জাতীয় কোডটির সদৃশ করতে এটি অক্ষম বলে মনে হয়।
আমি যে সমাধানটি সামনে আসতে পারলাম তা হ'ল একটি ফাংশন যা পুরো ডেটা স্ট্রাকচারে প্রথমে একটি ফাংশন কল করে এবং তারপরে পুনরাবৃত্তির সাথে ফলাফলের মতো করে:
recurseAfter :: (Expr -> Expr) -> Expr -> Expr
recurseAfter f x =
case f x of
Add xs ->
Add $ map (recurseAfter f) xs
Sub x y ->
Sub (recurseAfter f x) (recurseAfter f y)
other -> other
substituteName :: String -> Int -> Expr -> Expr
substituteName name newValue =
recurseAfter $ \case
Variable x
| x == name -> Number newValue
other -> other
replaceSubWithAdd :: Expr -> Expr
replaceSubWithAdd =
recurseAfter $ \case
Sub x (Number y) ->
Add [x, Number (-y)]
other -> other
তবে আমি মনে করি এটির আগে থেকে ইতিমধ্যে করার একটি সহজ উপায় থাকতে হবে। আমি কিছু অনুপস্থিত করছি?
Add :: Expr -> Expr -> Expr
পরিবর্তে সংজ্ঞা দিন Add :: [Expr] -> Expr
এবং Sub
পুরোপুরি পরিত্রাণ পান ।
recurseAfter
হয় ana
ছদ্মবেশে। আপনি অ্যানোরমিজমগুলি এবং দেখতে চাইতে পারেন recursion-schemes
। বলা হচ্ছে, আমি মনে করি আপনার চূড়ান্ত সমাধানটি যতটা সংক্ষিপ্ত হতে পারে। অফিশিয়াল recursion-schemes
অ্যানোমার্ফিজমগুলিতে স্যুইচ করা বেশি কিছু বাঁচবে না।