Difference between revisions of "Cookbook/Lists and strings"

From HaskellWiki
Jump to navigation Jump to search
m (import Char -> import Data.Char)
(21 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
== Lists ==
Since strings are lists of characters, you can use any available list function.
 
   
  +
In Haskell, lists are what Arrays are in most other languages.
= Lists =
 
   
 
=== Creating simple lists ===
In Haskell, lists are what Arrays are in most other languages. Haskell has all of the general list manipulation functions, see also <hask>Data.List</hask>.
 
   
  +
{| class="wikitable"
<haskell>
 
  +
|-
head [1,2,3] --> 1
 
  +
! Problem
tail [1,2,3] --> [2,3]
 
  +
! Solution
length [1,2,3] --> 3
 
  +
! Examples
init [1,2,3] --> [1,2]
 
  +
|-
last [1,2,3] --> 3
 
  +
| creating a list with given elements
  +
| -
 
|<haskell>
  +
3 : 12 : 42 : [] --> [3,12,42]
  +
'f' : 'o' : 'o' : [] --> "foo"
 
</haskell>
 
</haskell>
  +
|-
 
  +
| creating a list with stepsize 1
Furthermore, Haskell supports some neat concepts.
 
  +
| -
 
 
|<haskell>
== Infinite lists ==
 
  +
[1..10] --> [1,2,3,4,5,6,7,8,9,10]
<haskell>
 
  +
['a'..'z'] --> "abcdefghijklmnopqrstuvwxyz"
Prelude> [1..]
 
 
</haskell>
 
</haskell>
  +
|-
 
  +
| creating a list with different stepsize
The list of all squares:
 
  +
| -
<haskell>
+
|<haskell>
square x = x*x
 
 
[1,3..10] --> [1,3,5,7,9]
squares = map square [1..]
 
  +
['a','c'..'z'] --> "acegikmoqsuwy"
 
</haskell>
 
</haskell>
  +
|-
 
  +
| creating an infinite constant list
But in the end, you probably don't want to use infinite lists, but make them finite. You can do this with <hask>take</hask>:
 
  +
| -
 
<haskell>
+
|<haskell>
  +
[1,1..] --> [1,1,1,1,1,...
Prelude> take 10 squares
 
[1,4,9,16,25,36,49,64,81,100]
 
 
</haskell>
 
</haskell>
  +
|-
  +
| creating an infinite list with stepsize 1
  +
| -
  +
| <haskell>
  +
[1..] --> [1,2,3,4,5,...
  +
</haskell>
  +
|}
   
== List comprehensions ==
+
=== List comprehensions ===
   
 
The list of all squares can also be written in a more comprehensive way, using list comprehensions:
 
The list of all squares can also be written in a more comprehensive way, using list comprehensions:
Line 49: Line 61:
   
   
== Combining lists ==
+
=== Combining lists ===
   
 
{| class="wikitable"
 
{| class="wikitable"
Line 57: Line 69:
 
! Examples
 
! Examples
 
|-
 
|-
| combining two strings
+
| combining two lists
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3A%2B%2B (++)]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3A%2B%2B (++)]
 
|<haskell>
 
|<haskell>
 
"foo" ++ "bar" --> "foobar"
 
"foo" ++ "bar" --> "foobar"
  +
[42,43] ++ [60,61] --> [42,43,60,61]
 
</haskell>
 
</haskell>
 
|-
 
|-
| combining many strings
+
| combining many lists
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:concat concat]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:concat concat]
 
| <haskell>
 
| <haskell>
Line 70: Line 83:
 
|}
 
|}
   
== Accessing sublists ==
+
=== Accessing sublists ===
   
 
{| class="wikitable"
 
{| class="wikitable"
Line 78: Line 91:
 
! Examples
 
! Examples
 
|-
 
|-
| accessing the first character
+
| accessing the first element
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:head head]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:head head]
 
|<haskell>
 
|<haskell>
Line 84: Line 97:
 
</haskell>
 
</haskell>
 
|-
 
|-
| accessing the last character
+
| accessing the last element
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3Alast last]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3Alast last]
 
|<haskell>
 
|<haskell>
Line 90: Line 103:
 
</haskell>
 
</haskell>
 
|-
 
|-
| accessing the character at a given index
+
| accessing the element at a given index
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3A!! (!!)]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3A!! (!!)]
 
|<haskell>
 
|<haskell>
Line 96: Line 109:
 
</haskell>
 
</haskell>
 
|-
 
|-
| accessing the first <code>n</code> characters
+
| accessing the first <code>n</code> elements
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:take take]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:take take]
 
| <haskell>
 
| <haskell>
Line 102: Line 115:
 
</haskell>
 
</haskell>
 
|-
 
|-
| accessing the last <code>n</code> characters
+
| accessing the last <code>n</code> elements
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:reverse reverse ], [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:take take]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:reverse reverse ], [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:take take]
 
| <haskell>
 
| <haskell>
Line 108: Line 121:
 
</haskell>
 
</haskell>
 
|-
 
|-
| accessing the <code>n</code> characters starting from index <code>m</code>
+
| accessing the <code>n</code> elements starting from index <code>m</code>
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:drop drop], [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:take take]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:drop drop], [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:take take]
 
| <haskell>
 
| <haskell>
Line 115: Line 128:
 
|}
 
|}
   
== Splitting lists ==
+
=== Splitting lists ===
   
   
Line 129: Line 142:
 
</haskell>
 
</haskell>
 
|-
 
|-
| splitting a string into two parts
+
| splitting a list into two parts
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3AsplitAt splitAt]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v%3AsplitAt splitAt]
 
| <haskell>splitAt 3 "foo bar baz" --> ("foo"," bar baz")
 
| <haskell>splitAt 3 "foo bar baz" --> ("foo"," bar baz")
Line 135: Line 148:
 
|}
 
|}
   
= Strings =
+
== Strings ==
   
 
Since strings are lists of characters, you can use any available list function.
== Multiline strings ==
 
  +
 
=== Multiline strings ===
 
<haskell>
 
<haskell>
 
"foo\
 
"foo\
Line 143: Line 158:
 
</haskell>
 
</haskell>
   
== Converting between characters and values ==
+
=== Converting between characters and values ===
   
 
{| class="wikitable"
 
{| class="wikitable"
Line 166: Line 181:
 
|}
 
|}
   
== Reversing a string by words or characters ==
+
=== Reversing a string by words or characters ===
   
 
{| class="wikitable"
 
{| class="wikitable"
Line 193: Line 208:
 
|}
 
|}
   
== Converting case ==
+
=== Converting case ===
   
 
{| class="wikitable"
 
{| class="wikitable"
Line 204: Line 219:
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html#v%3AtoUpper toUpper]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html#v%3AtoUpper toUpper]
 
|<haskell>
 
|<haskell>
import Char
+
import Data.Char
 
toUpper 'a' --> "A"
 
toUpper 'a' --> "A"
 
</haskell>
 
</haskell>
Line 211: Line 226:
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html#v%3AtoLower toLower]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html#v%3AtoLower toLower]
 
| <haskell>
 
| <haskell>
import Char
+
import Data.Char
 
toLower 'A' --> "a"
 
toLower 'A' --> "a"
 
</haskell>
 
</haskell>
Line 218: Line 233:
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html#v%3AtoUpper toUpper], [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:map map]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html#v%3AtoUpper toUpper], [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:map map]
 
|<haskell>
 
|<haskell>
import Char
+
import Data.Char
 
map toUpper "Foo Bar" --> "FOO BAR"
 
map toUpper "Foo Bar" --> "FOO BAR"
 
</haskell>
 
</haskell>
Line 225: Line 240:
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html#v%3AtoLower toLower], [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:map map]
 
| [http://haskell.org/ghc/docs/latest/html/libraries/base/Data-Char.html#v%3AtoLower toLower], [http://haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:map map]
 
| <haskell>
 
| <haskell>
import Char
+
import Data.Char
 
map toLower "Foo Bar" --> "foo bar"
 
map toLower "Foo Bar" --> "foo bar"
 
</haskell>
 
</haskell>
 
|}
 
|}
   
== Interpolation ==
+
=== Interpolation ===
   
 
TODO
 
TODO
   
== Performance ==
+
=== Performance ===
   
 
For high performance requirements (where you would typically consider
 
For high performance requirements (where you would typically consider
 
C), consider using [http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html Data.ByteString].
 
C), consider using [http://hackage.haskell.org/packages/archive/bytestring/latest/doc/html/Data-ByteString.html Data.ByteString].
   
== Unicode ==
+
=== Unicode ===
   
 
TODO
 
TODO

Revision as of 14:42, 21 June 2013

Lists

In Haskell, lists are what Arrays are in most other languages.

Creating simple lists

Problem Solution Examples
creating a list with given elements -
3 : 12 : 42 : []        --> [3,12,42]
'f' : 'o' : 'o' : []    --> "foo"
creating a list with stepsize 1 -
[1..10]                 --> [1,2,3,4,5,6,7,8,9,10]
['a'..'z']              --> "abcdefghijklmnopqrstuvwxyz"
creating a list with different stepsize -
[1,3..10]               --> [1,3,5,7,9]
['a','c'..'z']          --> "acegikmoqsuwy"
creating an infinite constant list -
[1,1..]                   --> [1,1,1,1,1,...
creating an infinite list with stepsize 1 -
[1..]                 --> [1,2,3,4,5,...

List comprehensions

The list of all squares can also be written in a more comprehensive way, using list comprehensions:

squares = [x*x | x <- [1..]]

List comprehensions allow for constraints as well:

-- multiples of 3 or 5
mults = [ x | x <- [1..], mod x 3 == 0 || mod x 5 == 0 ]


Combining lists

Problem Solution Examples
combining two lists (++)
"foo" ++ "bar"                  --> "foobar"
[42,43] ++ [60,61]              --> [42,43,60,61]
combining many lists concat
concat ["foo", "bar", "baz"]    --> "foobarbaz"

Accessing sublists

Problem Solution Examples
accessing the first element head
head "foo bar baz"      --> 'f'
accessing the last element last
last "foo bar baz"      --> 'z'
accessing the element at a given index (!!)
"foo bar baz" !! 4      --> 'b'
accessing the first n elements take
take 3 "foo bar baz"    --> "foo"
accessing the last n elements reverse , take
reverse . take 3 . reverse $ "foobar"    --> "bar"
accessing the n elements starting from index m drop, take
take 4 $ drop 2 "foo bar baz"            --> "o ba"

Splitting lists

Problem Solution Examples
splitting a string into a list of words words
words "foo bar\t baz\n"    --> ["foo","bar","baz"]
splitting a list into two parts splitAt
splitAt 3 "foo bar baz"    --> ("foo"," bar baz")

Strings

Since strings are lists of characters, you can use any available list function.

Multiline strings

"foo\
\bar"               --> "foobar"

Converting between characters and values

Problem Solution Examples
converting a character to a numeric value ord
import Char
ord 'A'    --> 65
converting a numeric value to a character chr
import Char
chr 99     --> 'c'

Reversing a string by words or characters

Problem Solution Examples
reversing a string by characters reverse
reverse "foo bar baz"                        --> "zab rab oof"
reversing a string by words words, reverse, unwords
unwords $ reverse $ words "foo bar baz"      --> "baz bar foo"
reversing a string by characters by words words, reverse, map, unwords
unwords $ map reverse $ words "foo bar baz"  --> "oof rab zab"

Converting case

Problem Solution Examples
converting a character to upper-case toUpper
import Data.Char
toUpper 'a'            --> "A"
converting a character to lower-case toLower
import Data.Char
toLower 'A'            --> "a"
converting a string to upper-case toUpper, map
import Data.Char
map toUpper "Foo Bar"  --> "FOO BAR"
converting a string to lower-case toLower, map
import Data.Char
map toLower "Foo Bar"  --> "foo bar"

Interpolation

TODO

Performance

For high performance requirements (where you would typically consider C), consider using Data.ByteString.

Unicode

TODO