ここで快適なことの 1 つは、標準の Haskell リストが細かいスタックであることです (当然のことながら、スタックはより制限された種類のリストであることを念頭に置いてください)。関数は次のようになります。
--takes one string and uses a stack to convert it to another string
doSomethingWithStack :: String -> [String] -> String
doSomethingWithStack str stack =
let str' = --here you embody your points 2 and 3
stack' = --stack top is (head stack), push is (x : stack), pop is (tail stack)
--... any change you'd want to make to any value turns into a new variable
in case stack'' of --check the final variables
[] -> str'' --if stack is empty, end
_ -> doSomethingWithStack str'' stack'' --if not, repeat
--now, to make it pretty
fancyWrapper :: String -> String
fancyWrapper str = doSomethingWithStack str [] -- empty list is an empty stack
--because you should strive to separate pure and impure functions
--, I suggest that you do the print elsewhere, say
main = do
str <- getLine
print $ fancyWrapper str
少なすぎず多すぎないことを願っています。問題が発生したら、試してみて、より具体的な質問をしてください。