Haskell函数相加实现与13-15位数字处理问题求解
Hey there, fellow Haskell newbie! Let's work through your problem together—we'll start with the number processing task you described, then cover how to combine functions (since you mentioned "function addition," I assume you mean composing functions to chain operations seamlessly).
Your task has two clear, sequential steps:
- Remove the last digit of a 13-15 digit number
- Double every odd digit in the resulting number
Let's tackle each step individually, then bring them together.
First: Remove the Last Digit
If you're working with integer values, the simplest approach is to use integer division by 10 with div—this automatically drops the last digit without any string conversion:
removeLastDigit :: Integer -> Integer removeLastDigit n = n `div` 10
We use Integer instead of Int here because 15-digit numbers can exceed the maximum value of a 32-bit Int (around 2 billion). Integer handles arbitrary-precision integers safely, so no overflow worries.
If you're starting with a string input (like direct user input), you can just take all characters except the last one with init:
removeLastDigitStr :: String -> String removeLastDigitStr = init
Note: init will throw an error if given an empty string, but since your input is guaranteed to be 13-15 digits, this is totally safe.
Second: Double Every Odd Digit
Next, we need to process each digit: check if it's odd, and double it if so. Let's cover both integer and string workflows.
For Integers
First, we'll convert the integer to a list of its individual digits, process each digit, then convert the list back to an integer:
-- Helper: Convert an Integer to a list of its digits digits :: Integer -> [Integer] digits 0 = [] digits n = digits (n `div` 10) ++ [n `mod` 10] -- Helper: Convert a list of digits back to an Integer undigits :: [Integer] -> Integer undigits = foldl (\acc d -> acc * 10 + d) 0 -- Double every odd digit in the number doubleOddDigits :: Integer -> Integer doubleOddDigits = undigits . map (\d -> if d `mod` 2 == 1 then d * 2 else d) . digits
For Strings
If you're working with a string of digits, this is even more straightforward—convert each character to its numeric value, process it, then convert back to a character (or string, for cases like 9→18):
doubleOddDigitsStr :: String -> String doubleOddDigitsStr = concatMap processDigit where processDigit c = let d = read [c] :: Integer in if d `mod` 2 == 1 then show (d * 2) else [c]
I used concatMap here because doubling an odd digit like 9 gives 18 (two characters)—this ensures we flatten the result into a single string instead of a list of strings.
Now that we have our two core functions, we can chain them together using Haskell's function composition operator .. This takes the output of one function and feeds it directly as input to the next—exactly what we need for your sequential task.
For integers:
processNumber :: Integer -> Integer processNumber = doubleOddDigits . removeLastDigit
This reads as: first apply removeLastDigit to the input number, then take that result and apply doubleOddDigits.
For strings:
processNumberStr :: String -> String processNumberStr = doubleOddDigitsStr . removeLastDigitStr
Let's test this with your example input:
- Input:
19283828382133 - After removing last digit:
1928382838213 - After doubling odd digits:
21828682868226(as integer) or"21828682868226"(as string)
If you want to build a small program that takes user input, here's a complete example with input validation to ensure the input is a valid 13-15 digit number:
import Data.Char (isDigit) isValidInput :: String -> Bool isValidInput s = length s `elem` [13,14,15] && all isDigit s removeLastDigitStr :: String -> String removeLastDigitStr = init doubleOddDigitsStr :: String -> String doubleOddDigitsStr = concatMap processDigit where processDigit c = let d = read [c] :: Integer in if d `mod` 2 == 1 then show (d * 2) else [c] processNumberStr :: String -> String processNumberStr = doubleOddDigitsStr . removeLastDigitStr main :: IO () main = do putStrLn "Enter a 13-15 digit number:" input <- getLine if isValidInput input then putStrLn $ "Processed result: " ++ processNumberStr input else putStrLn "Error: Please enter a valid 13-15 digit number (only digits allowed)."
内容的提问来源于stack exchange,提问作者cars

