Haskell如何读取句子、拆分单词并对每个单词应用自定义函数?
Got it, let's fix this up so you can process an entire sentence instead of just a single word. The core issue with your current code is that it treats the whole input line as one big word—we need to split the sentence into individual words, process each one, then put them back together.
First, let's break down what we need to do step by step:
- Split the input sentence into a list of words
- For each word:
- If it's short (length ≤ 2), leave it as-is (no need to shuffle nothing!)
- If it's longer, grab the first and last characters, shuffle the middle part, then recombine
- Join all processed words back into a single sentence
- Output the result
Let's refactor your code to make this work:
First, let's create a dedicated function to process a single word. This wraps up the logic you already have, but handles short words gracefully:
import Data.List import System.IO import System.Random import Data.Array.IO import Control.Monad -- Get the middle characters (drop first, remove last) devContent :: [Char] -> [Char] devContent x = init (drop 1 x) -- Shuffle a list (your existing shuffle function, kept as-is) aleatorio :: [d] -> IO [d] aleatorio xs = do let n = length xs ar <- newListArray (1, n) xs forM [1..n] $ \i -> do t <- randomRIO (i, n) vi <- readArray ar i vt <- readArray ar t writeArray ar t vi return vt -- Process a single word: keep first/last, shuffle middle (handle short words) processWord :: String -> IO String processWord word | length word <= 2 = return word -- No shuffle needed for short words | otherwise = do let firstChar = head word lastChar = last word middle = devContent word shuffledMiddle <- aleatorio middle return $ firstChar : shuffledMiddle ++ [lastChar]
Now, let's update the main logic to handle an entire sentence. We'll use words to split the input into words, apply our processWord to each one, then use unwords to stitch them back together:
processSentence :: IO () processSentence = do putStrLn "Enter a sentence:" frase <- getLine -- Process every word in the input sentence processedWords <- mapM processWord (words frase) -- Combine processed words back into a single sentence let result = unwords processedWords putStrLn "Processed sentence:" putStrLn result -- Run the program main :: IO () main = processSentence
Let's test this with your example: if you input "Hello world", you might get something like Hlleo wlrod (the shuffle is random, so the middle letters will change each time you run it).
A quick heads-up on edge cases:
- The
wordsfunction splits on whitespace, so it handles spaces between words but won't separate punctuation attached to words (like "Hello!"). If you need to handle punctuation, you'd need extra logic to split words from their surrounding punctuation first. - We added the short-word check because shuffling an empty list (for 2-letter words) would technically work, but returning the original word is more intuitive.
You can compile and run this like any Haskell program: save it to a file (e.g., WordShuffler.hs), run ghc WordShuffler.hs, then execute the generated binary.
内容的提问来源于stack exchange,提问作者Alan Rodriguez

