# :: Eq a => [a] -> [a] -> [a] -> [a]

Given a list and a replacement list, replaces each occurance of the search list with the replacement list in the operation list. Example:
```replace "," "." "127,0,0,1" -> "127.0.0.1"
```
This could logically be thought of as:
```replace old new l = join new . split old \$ l
```
Replace each occurrence of one sublist in a list with another.
Replace a subsequence everywhere it occurs. The first argument must not be the empty list.
```replace "el" "_" "Hello Bella" == "H_lo B_la"
replace "el" "e" "Hello"       == "Helo"
replace "" "e" "Hello"         == undefined
\xs ys -> not (null xs) ==> replace xs xs ys == ys
```
Replaces a subsequence by another in a sequence Taken from http://bluebones.net/2007/01/replace-in-haskell/
```>>> replace "foo" "baz" "foobar"
"bazbar"

>>> replace "some" "thing" "something something"
"thingthing thingthing"

>>> replace "not" "" "something"
"something"

>>> replace "" "here" "something"
"heresomething"
```
substituteVar a b w replaces a free variable a with another free variable b in w.
```>>> substituteVar "Alice" "Bob" ["Alice","Bob","Charlie"]
["Bob","Bob","Charlie"]
```
zipWith generalises zip by zipping with the function given as the first argument, instead of a tupling function. For example, zipWith (+) is applied to two lists to produce the list of corresponding sums. zipWith is right-lazy:
```zipWith f [] _|_ = []
```
```zipWithExact f xs ys =
| length xs == length ys = zipWith f xs ys
| otherwise              = error "some message"
```
zipWith generalises zip by zipping with the function given as the first argument, instead of a tupling function. For example, zipWith (+) is applied to two lists to produce the list of corresponding sums.
Zip two lists which must be of the same length. This is checked only lazily, that is unequal lengths are detected only if the list is evaluated completely. But it is more strict than zipWithPad undefined f since the latter one may succeed on unequal length list if f is lazy.
zipWith generalises zip by zipping with the function given as the first argument, instead of a tupling function. For example, zipWith (+) is applied to two lists to produce the list of corresponding sums. zipWith is right-lazy:
```zipWith f [] _|_ = []
```
zipWithLazy is like zipWith but is lazy in the second list. The length of the output is always the same as the length of the first list.
substitute a p w replaces the free variable a with p in w.
```>>> substitute "hello" ["goodnight","Gracie"] ["hello","!!!"]
["goodnight","Gracie","!!!"]
```
zip3 takes three lists and returns a list of triples, analogous to zip.
```zip3Exact xs ys zs =
| length xs == length ys && length xs == length zs = zip3 xs ys zs
| otherwise                                        = error "some message"
```
Operate on each combination of elements of the first and the second list. In contrast to the list instance of liftM2 in holds the results in a list of lists. It holds concat (outerProduct f xs ys) == liftM2 f xs ys
Binary parallel composition. Each filter uses a copy of the input, rather than one filter using the result of the other. (Has a more general type than just CFilter.)
Directional choice: in f |>| g give g-productions only if no f-productions