packages feed

chimera-0.2.0.0: README.md

# chimera

Lazy, infinite streams with O(1) indexing.
Most useful to memoize functions.

## Example 1

Consider following predicate:

```haskell
isOdd :: Word -> Bool
isOdd 0 = False
isOdd n = not (isOdd (n - 1))
```

Its computation is expensive, so we'd like to memoize its values into
`Chimera` using `tabulate` and access this stream via `index`
instead of recalculation of `isOdd`:

```haskell
isOddBS :: Chimera
isOddBS = tabulate isOdd

isOdd' :: Word -> Bool
isOdd' = index isOddBS
```

We can do even better by replacing part of recursive calls to `isOdd`
by indexing memoized values. Write `isOddF`
such that `isOdd = fix isOddF`:

```haskell
isOddF :: (Word -> Bool) -> Word -> Bool
isOddF _ 0 = False
isOddF f n = not (f (n - 1))
```

and use `tabulateFix`:

```haskell
isOddBS :: Chimera
isOddBS = tabulateFix isOddF

isOdd' :: Word -> Bool
isOdd' = index isOddBS
```

## Example 2

Define a predicate, which checks whether its argument is
a prime number by trial division.

```haskell
isPrime :: Word -> Bool
isPrime n
  | n < 2     = False
  | n < 4     = True
  | even n    = False
  | otherwise = and [ n `rem` d /= 0 | d <- [3, 5 .. ceiling (sqrt (fromIntegral n))], isPrime d]
```

Convert it to unfixed form:

```haskell
isPrimeF :: (Word -> Bool) -> Word -> Bool
isPrimeF f n
  | n < 2     = False
  | n < 4     = True
  | even n    = False
  | otherwise = and [ n `rem` d /= 0 | d <- [3, 5 .. ceiling (sqrt (fromIntegral n))], f d]
```

Create its memoized version for faster evaluation:

```haskell
isPrimeBS :: Chimera
isPrimeBS = tabulateFix isPrimeF

isPrime' :: Word -> Bool
isPrime' = index isPrimeBS
```