Strings and Characters
Prerequisites: List functions
Since String is [Char], strings use all the list functions. A few
extra functions are specific to text.
Words and lines
main :: IO ()
main = do
let sentence = " the quick brown fox "
print (words sentence)
putStrLn (unwords (words sentence))
print (lines "first\nsecond\nthird")
putStr (unlines ["one", "two"])
["the","quick","brown","fox"]
the quick brown fox
["first","second","third"]
one
two
words splits on any whitespace and drops the empty pieces; unwords
joins with single spaces. lines/unlines do the same with newlines.
Data.Char
import Data.Char (toUpper, toLower, isDigit, isAlpha, isSpace, ord, chr, digitToInt)
capitalize :: String -> String
capitalize "" = ""
capitalize (c : cs) = toUpper c : map toLower cs
main :: IO ()
main = do
putStrLn (capitalize "hASKELL")
print (filter isDigit "Call 555-0123 now")
print (all isAlpha "Haskell", any isSpace "no spaces")
print (ord 'A', chr 97)
print (sum (map digitToInt "2024"))
Haskell
"5550123"
(True,True)
(65,'a')
8
show and read
show turns a value into a string; read parses one — you must say
which type you want:
main :: IO ()
main = do
putStrLn (show 3.5 ++ " and " ++ show True)
print (read "42" + 1 :: Int)
print (read "[1,2,3]" :: [Int])
print (read "(1,\"one\")" :: (Int, String))
3.5 and True
43
[1,2,3]
(1,"one")
read crashes on bad input (read "abc" :: Int). For user input, use
readMaybe from Text.Read, which returns Nothing instead:
import Text.Read (readMaybe)
main :: IO ()
main = do
print (readMaybe "42" :: Maybe Int)
print (readMaybe "4x2" :: Maybe Int)
print (readMaybe "3.5" :: Maybe Double)
Just 42
Nothing
Just 3.5
Escapes and multi-line strings
"\n" (newline), "\t" (tab), "\"" (quote), and "\\" (backslash)
work as in most languages. Since GHC 9.12, the MultilineStrings
extension adds triple-quoted """ strings; traditionally, long strings
are built with unlines or ++.
String versus Text
String is simple but slow and memory-hungry for large amounts of text,
because each character is a list cell. Real applications use
Data.Text from the text package, covered in Level 2.
Practice
Write isPalindrome :: String -> Bool that ignores case, spaces, and
punctuation, and test it on "A man, a plan, a canal: Panama".
Show solution
import Data.Char (isAlpha, toLower)
isPalindrome :: String -> Bool
isPalindrome s = cleaned == reverse cleaned
where
cleaned = map toLower (filter isAlpha s)
main :: IO ()
main = do
print (isPalindrome "A man, a plan, a canal: Panama")
print (isPalindrome "Haskell")
True
False