I want to remove the last character of a String, if it's a "!"
I know I want base cases, ie. if the string is empty:
remove [] = []
How do I index the last character? Using:
last
And, what's the best way to create an 'if, then' loop for this problem?
Should I use guards? |
CodePudding user response:
The Haskell way of solving this is with a recursion and pattern matching:
remove "" = "" -- obvious
remove "!" = "" -- that's what we're here for
remove (x:xs) = (x : remove xs) -- keep the head, proceed to the tail
Any attempts with last
and conditional constructions will be less elegant and efficient.
CodePudding user response:
You don't have to do this with a loop. Instead of such imperative thinking you can take a higher-level view and compose the program from several higher-order functions, getting this one-liner,
import Data.List (tails)
foo :: String -> String
foo = (take 1 =<<) . takeWhile (/= "!") . tails
-- = concat . map (take 1) . takeWhile (/= "!") . tails
or with list comprehensions,
foo xs = [c | (c:_) <- takeWhile (/= "!") $ tails xs]
tails
repeatedly takes tail
s of the input list, takeWhile
gets rid of the final '!'
, if any, and concatMap (take 1)
reconstitutes the string back from its tails
:
concatMap (take 1) . tails
is an identity operation on lists, and we're getting in on the action, in the middle.