Classy Strings
In January we shared many different examples of helpful functions you can use with lists. In Februrary, we'll be focusing on Strings. Of course, Haskell's different string representations all use lists to some extent, so we've already seen several examples of list manipulation being useful with strings. But now we'll look more specifically at the different types that all us to describe string-like data.
Our first useful idea is the IsString class. This can apply to any type that we can derive from a String. The key function is fromString
.
class IsString a where
fromString :: String -> a
Making an instance of this type is easy enough as long as your data makes sense. Suppose we have a simple newtype
wrapper for a string.
newtype Person = Person String
Our IsString
instance is trivial:
instance IsString Person where
fromString = Person
But sometimes we might want something a little trickier. Suppose we want to give our person a first AND last name, given only a single string.
data Person = Person
{ firstName :: String
, lastName :: String
} deriving (Show)
Now our instance is non-trivial, but still simple if we remember our helpful list functions! We first take all the characters that are "not spaces" to get the first name. Then to get the last name, we drop these characters instead, and then drop all the spaces as well!
instance IsString Person where
fromString s = Person firstName lastName
where
firstName = takeWhile (not . isSpace) s
lastName = dropWhile isSpace (dropWhile (not . isSpace) s)
We can use this instance in the simple way, applying the fromString
function directly:
>> fromString "George Washington" :: Person
Person {firstName = "George", lastName = "Washington"}
But what's more interesting is that if we turn on the "Overloaded Strings" extension, we can use a string literal for this object in our code!
>> :set -XOverloadedStrings
>> let president = "George Washington" :: Person
This compiler extension is extremely useful once we get to other kinds of strings (Text
, ByteString
, etc.). But, combined with the IsString
class, it's a nice little quirk that can make our lives easier in certain circumstances, especially when we are running some kind of parsing program, or pasting in stringified data into our Haskell source when we don't want to bother reformatting it.
We'll be back next Monday with more string tricks! If you want to use tricks like these in a project, you need to learn how to use Stack first. To help with this, sign up for our free Stack mini-course!