# Haskell a la carte

### From HaskellWiki

(Difference between revisions)

(This isn't quicksort, it is tree sort) |
DonStewart (Talk | contribs) (Revert to "qsort", the standard name for the last 20 years for this function. It's not mergesort.. See the talk page.) |
||

(4 intermediate revisions by 2 users not shown) | |||

Line 8: | Line 8: | ||

* | * | ||

<haskell> | <haskell> | ||

− | + | qsort :: Ord a => [a] -> [a] | |

− | + | qsort [] = [] | |

− | + | qsort (x:xs) = qsort (filter (<x) xs) ++ [x] ++ qsort (filter (>=x) xs)) | |

</haskell> | </haskell> | ||

− | :: | + | ::Quicksort in three lines (!). Sorts not only integers but anything that can be compared. But granted, it's not in-place. |

* | * | ||

Line 134: | Line 134: | ||

* | * | ||

<haskell> | <haskell> | ||

− | minimum = head . | + | minimum = head . qsort |

+ | </haskell> | ||

+ | :: To find the least element of a list, first sort and then take the first element. You think that takes too much time (<math>O(n\cdot\log n)</math> instead of <math>O(n)</math>)? Well, thanks to ''lazy evaluation'', it doesn't! In Haskell, expressions are evaluated only as much as needed. Therefore, the sorting won't proceed further than producing the first element of the sorted list. Ok, the sorting function has to play along and produce that one quickly, but many like quicksort (in the average case) or mergesort do so. | ||

+ | |||

+ | * | ||

+ | <haskell> | ||

+ | sum = foldr (+) 0 | ||

+ | product = foldr (*) 1 | ||

+ | concat = foldr (++) [] | ||

+ | </haskell> | ||

+ | :: Tired of implementing a recursive function every time you're traversing a list? No need for that, <hask>fold</hask> captures the recursion, you just tell it how to combine the list elements. It's defined as | ||

+ | <haskell> | ||

+ | foldr f z [] = z | ||

+ | foldr f z (x:xs) = x `f` foldr f z xs | ||

</haskell> | </haskell> | ||

− | |||

== Plats principaux == | == Plats principaux == | ||

Line 142: | Line 154: | ||

== Desserts== | == Desserts== | ||

Sugar-sweet and en passant. | Sugar-sweet and en passant. | ||

+ | |||

+ | * | ||

+ | <haskell> | ||

+ | sequence :: Monad m => [m a] -> m [a] | ||

+ | sequence = foldr (liftM2 (:)) (return []) | ||

+ | |||

+ | GHCi> sequence [[1,2],[3,4],[5,6]] | ||

+ | [[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]] | ||

+ | </haskell> | ||

+ | :: Execute a list of monadic effects in sequence. By using different monads, you get interesting results! In the list monad for example, <hask>sequence</hask> computes the cartesian product of lists. | ||

== Vins == | == Vins == |

## Latest revision as of 19:16, 14 June 2008

New to Haskell? This menu will give you a first impression. Don't read all the explanations, or you'll be starved before the meal.

## Contents |

## [edit] 1 Apéritifs

Foretaste of an excellent meal.

qsort :: Ord a => [a] -> [a] qsort [] = [] qsort (x:xs) = qsort (filter (<x) xs) ++ [x] ++ qsort (filter (>=x) xs))

- Quicksort in three lines (!). Sorts not only integers but anything that can be compared. But granted, it's not in-place.

fibs = 1:1:zipWith (+) fibs (tail fibs)

- The
*infinite*list of fibonacci numbers. Just don't try to print all of it.

- The

linecount = interact $ show . length . lines wordcount = interact $ show . length . words

- Count the number of lines or words from standard input.

## [edit] 2 Entrées

How to read the dishes.

square x = x*x

- is the function which maps a number to its square. While we commonly write parenthesis around function arguments in mathematics and most programming languages, a simple space is enough in Haskell. We're going to apply functions to arguments all around, so why clutter the notation with unnecessary ballast?

square :: Int -> Int square x = x*x

- Squaring again, this time with a
*type signature*which says that squaring maps integers to integers. In mathematics, we'd write . Every expression in Haskell has a type and the compiler will automatically infer (= figure out) one for you if you're too lazy to write down a type signature yourself. Of course, parenthesis are allowed for grouping, like inwhich is 36 compared tosquare (4+2)which is 16+2=18.square 4 + 2

- Squaring again, this time with a

square :: Num a => a -> a square x = x*x

- Squaring yet again, this time with a more general type signature. After all, we can square anything () that looks like a number (a). By the way, this general type is the one that the compiler will infer forNum aif you omit an explicit signature.square

- Squaring yet again, this time with a more general type signature. After all, we can square anything (

average x y = (x+y)/2

- The average of two numbers. Multiple arguments are separated by spaces.

average :: Double -> Double -> Double average x y = (x+y)/2

- Average again, this time with a type signature. Looks a bit strange, but that's the spicey
*currying*. In fact,is a function that takes only one argument (average) but returns a function with one argument (Double).Double -> Double

- Average again, this time with a type signature. Looks a bit strange, but that's the spicey

power a n = if n == 0 then 1 else a * power a (n-1)

*a*^{n}, defined with*recursion*. Assumes that the exponentis not negative, that isn.n >= 0- Recursion is the basic building block for iteration in Haskell, there are no
`for`

or`while`

-loops. Well, there are functions likeormapthat provide something similar. There is no need for special built-in control structures, you can define them yourself as ordinary functions (later).foldr

power a 0 = 1 power a n = a * power a (n-1)

- Exponentiation again, this time with
*pattern matching*. The first equation that matches will be chosen.

- Exponentiation again, this time with

length [] = 0 length (x:xs) = 1 + length xs

- Calculate the length of a
*list*. What's a list? Well, a list may either be empty () or be an element ([]) prepended (x) to another list (:). Read "xs" as the plural of "xs", that is as "ex-es". It's a list of other such elementsx, after all.x

- Calculate the length of a

length :: [a] -> Int length [] = 0 length (x:xs) = 1 + length xs

- Length of a list again, this time with type signature. is the type of lists with elements of type[a].acan be used for any such element type.length

- Length of a list again, this time with type signature.

head :: [a] -> a head (x:xs) = x

- First element of a list. Undefined for empty lists.

sum [] = 0 sum (x:xs) = x + sum xs

- Sum all elements of a list.

average xs = sum xs / (fromIntegral (length xs))

- Arithmetic mean. converts the integer result offromIntegralinto a decimal number for the divisionlength./

- Arithmetic mean.

(++) :: [a] -> [a] -> [a] (++) [] ys = ys (++) (x:xs) ys = x:(xs ++ ys)

- Concatenate two lists. Custom infix operators can be defined freely.

## [edit] 3 Soupes

The best soup is made by combining the available ingredients.

(.) :: (b -> c) -> (a -> b) -> (a -> c) (.) f g x = f (g x) fourthPower = square . square

- The dot is good old function composition . First apply g, then apply f. Simple example: squaring something twice.f . g

- The dot

minimum = head . qsort

- To find the least element of a list, first sort and then take the first element. You think that takes too much time ( instead of
*O*(*n*))? Well, thanks to*lazy evaluation*, it doesn't! In Haskell, expressions are evaluated only as much as needed. Therefore, the sorting won't proceed further than producing the first element of the sorted list. Ok, the sorting function has to play along and produce that one quickly, but many like quicksort (in the average case) or mergesort do so.

- To find the least element of a list, first sort and then take the first element. You think that takes too much time ( instead of

sum = foldr (+) 0 product = foldr (*) 1 concat = foldr (++) []

- Tired of implementing a recursive function every time you're traversing a list? No need for that, captures the recursion, you just tell it how to combine the list elements. It's defined asfold

- Tired of implementing a recursive function every time you're traversing a list? No need for that,

foldr f z [] = z foldr f z (x:xs) = x `f` foldr f z xs

## [edit] 4 Plats principaux

## [edit] 5 Desserts

Sugar-sweet and en passant.

sequence :: Monad m => [m a] -> m [a] sequence = foldr (liftM2 (:)) (return []) GHCi> sequence [[1,2],[3,4],[5,6]] [[1,3,5],[1,3,6],[1,4,5],[1,4,6],[2,3,5],[2,3,6],[2,4,5],[2,4,6]]

- Execute a list of monadic effects in sequence. By using different monads, you get interesting results! In the list monad for example, computes the cartesian product of lists.sequence

- Execute a list of monadic effects in sequence. By using different monads, you get interesting results! In the list monad for example,

## [edit] 6 Vins

` apfelmus 2007`

- Wait, that's the author! Hiccup!