Add permutations and LazyList.length to Util
This commit is contained in:
parent
c632ab023d
commit
ac93582e96
154
src/Util.md
154
src/Util.md
|
@ -10,6 +10,7 @@ import Data.SortedSet
|
|||
import Data.String
|
||||
import Data.List.Lazy
|
||||
import Data.List1
|
||||
import Data.Vect
|
||||
|
||||
%default total
|
||||
```
|
||||
|
@ -56,13 +57,13 @@ namespace List
|
|||
Returns `True` if the list contains the given value
|
||||
|
||||
```idris
|
||||
export
|
||||
contains : Eq a => a -> List a -> Bool
|
||||
contains x [] = False
|
||||
contains x (y :: xs) =
|
||||
if x == y
|
||||
then True
|
||||
else contains x xs
|
||||
export
|
||||
contains : Eq a => a -> List a -> Bool
|
||||
contains x [] = False
|
||||
contains x (y :: xs) =
|
||||
if x == y
|
||||
then True
|
||||
else contains x xs
|
||||
```
|
||||
|
||||
### rotations
|
||||
|
@ -76,16 +77,64 @@ rotations [1, 2, 3] == [[1, 2, 3], [3, 1, 2], [2, 3, 1]]
|
|||
```
|
||||
|
||||
```idris
|
||||
export
|
||||
rotations : List a -> List (List a)
|
||||
rotations xs = rotations' (length xs) xs []
|
||||
where
|
||||
rotations' : Nat -> List a -> (acc : List (List a)) -> List (List a)
|
||||
rotations' 0 xs acc = acc
|
||||
rotations' (S k) [] acc = acc
|
||||
rotations' (S k) (x :: xs) acc =
|
||||
let next = xs ++ [x]
|
||||
in rotations' k next (next :: acc)
|
||||
export
|
||||
rotations : List a -> List (List a)
|
||||
rotations xs = rotations' (length xs) xs []
|
||||
where
|
||||
rotations' : Nat -> List a -> (acc : List (List a)) -> List (List a)
|
||||
rotations' 0 xs acc = acc
|
||||
rotations' (S k) [] acc = acc
|
||||
rotations' (S k) (x :: xs) acc =
|
||||
let next = xs ++ [x]
|
||||
in rotations' k next (next :: acc)
|
||||
```
|
||||
|
||||
### permutations
|
||||
|
||||
Lazily generate all of the permutations of a list
|
||||
|
||||
```idris
|
||||
export
|
||||
permutations : List a -> LazyList (List a)
|
||||
permutations [] = pure []
|
||||
permutations xs = do
|
||||
(head, tail) <- select xs
|
||||
tail <- permutations (assert_smaller xs tail)
|
||||
pure $ head :: tail
|
||||
where
|
||||
consSnd : a -> (a, List a) -> (a, List a)
|
||||
consSnd x (y, xs) = (y, x :: xs)
|
||||
select : List a -> LazyList (a, List a)
|
||||
select [] = []
|
||||
select (x :: xs) = (x, xs) :: map (consSnd x) (select xs)
|
||||
```
|
||||
|
||||
## Vect
|
||||
|
||||
```idris hide
|
||||
namespace Vect
|
||||
```
|
||||
|
||||
### permutations
|
||||
|
||||
Lazily generate all the permutations of a Vect
|
||||
|
||||
```idris
|
||||
export
|
||||
permutations : Vect n a -> LazyList (Vect n a)
|
||||
permutations [] = []
|
||||
permutations [x] = [[x]]
|
||||
permutations (x :: xs) = do
|
||||
(head, tail) <- select (x :: xs)
|
||||
tail <- permutations tail
|
||||
pure $ head :: tail
|
||||
where
|
||||
consSnd : a -> (a, Vect m a) -> (a, Vect (S m) a)
|
||||
consSnd x (y, xs) = (y, x :: xs)
|
||||
select : Vect (S m) a -> LazyList (a, Vect m a)
|
||||
select [y] = [(y, [])]
|
||||
select (y :: (z :: ys)) =
|
||||
(y, z :: ys) :: map (consSnd y) (select (z :: ys))
|
||||
```
|
||||
|
||||
## Vectors
|
||||
|
@ -166,20 +215,24 @@ off of the string at a time, checking if the needle is a prefix at each step.
|
|||
|
||||
### Cartesian product
|
||||
|
||||
```idris hide
|
||||
namespace LazyList
|
||||
```
|
||||
|
||||
Lazily take the cartesian product of two foldables
|
||||
|
||||
```idris
|
||||
export
|
||||
cartProd : Foldable a => Foldable b => a e -> b f -> LazyList (e, f)
|
||||
cartProd x y =
|
||||
let y = foldToLazy y
|
||||
in foldr (\e, acc => combine e y acc) [] x
|
||||
where
|
||||
foldToLazy : Foldable a' => a' e' -> LazyList e'
|
||||
foldToLazy x = foldr (\e, acc => e :: acc) [] x
|
||||
combine : e -> LazyList f -> LazyList (e, f) -> LazyList (e, f)
|
||||
combine x [] rest = rest
|
||||
combine x (y :: ys) rest = (x, y) :: combine x ys rest
|
||||
export
|
||||
cartProd : Foldable a => Foldable b => a e -> b f -> LazyList (e, f)
|
||||
cartProd x y =
|
||||
let y = foldToLazy y
|
||||
in foldr (\e, acc => combine e y acc) [] x
|
||||
where
|
||||
foldToLazy : Foldable a' => a' e' -> LazyList e'
|
||||
foldToLazy x = foldr (\e, acc => e :: acc) [] x
|
||||
combine : e -> LazyList f -> LazyList (e, f) -> LazyList (e, f)
|
||||
combine x [] rest = rest
|
||||
combine x (y :: ys) rest = (x, y) :: combine x ys rest
|
||||
```
|
||||
|
||||
### Concat
|
||||
|
@ -187,10 +240,10 @@ cartProd x y =
|
|||
Lazily concatenate a LazyList of LazyLists
|
||||
|
||||
```idris
|
||||
export
|
||||
lazyConcat : LazyList (LazyList a) -> LazyList a
|
||||
lazyConcat [] = []
|
||||
lazyConcat (x :: xs) = x ++ lazyConcat xs
|
||||
export
|
||||
lazyConcat : LazyList (LazyList a) -> LazyList a
|
||||
lazyConcat [] = []
|
||||
lazyConcat (x :: xs) = x ++ lazyConcat xs
|
||||
```
|
||||
|
||||
### Group
|
||||
|
@ -198,15 +251,30 @@ lazyConcat (x :: xs) = x ++ lazyConcat xs
|
|||
Lazily group a LazyList
|
||||
|
||||
```idris
|
||||
export
|
||||
lazyGroup : Eq a => LazyList a -> LazyList (List1 a)
|
||||
lazyGroup [] = []
|
||||
lazyGroup (x :: xs) = lazyGroup' xs x (x ::: [])
|
||||
where
|
||||
lazyGroup' : LazyList a -> (current : a) -> (acc : List1 a) -> LazyList (List1 a)
|
||||
lazyGroup' [] current acc = [acc]
|
||||
lazyGroup' (y :: ys) current acc@(head ::: tail) =
|
||||
if y == current
|
||||
then lazyGroup' ys current (head ::: (y :: tail))
|
||||
else acc :: lazyGroup (y :: ys)
|
||||
export
|
||||
lazyGroup : Eq a => LazyList a -> LazyList (List1 a)
|
||||
lazyGroup [] = []
|
||||
lazyGroup (x :: xs) = lazyGroup' xs x (x ::: [])
|
||||
where
|
||||
lazyGroup' : LazyList a -> (current : a) -> (acc : List1 a)
|
||||
-> LazyList (List1 a)
|
||||
lazyGroup' [] current acc = [acc]
|
||||
lazyGroup' (y :: ys) current acc@(head ::: tail) =
|
||||
if y == current
|
||||
then lazyGroup' ys current (head ::: (y :: tail))
|
||||
else acc :: lazyGroup (y :: ys)
|
||||
```
|
||||
|
||||
### length
|
||||
|
||||
Calculate the length of a LazyList
|
||||
|
||||
```idris
|
||||
export
|
||||
length : LazyList a -> Nat
|
||||
length = length' 0
|
||||
where
|
||||
length' : Nat -> LazyList a -> Nat
|
||||
length' k [] = k
|
||||
length' k (x :: xs) = length' (S k) xs
|
||||
```
|
||||
|
|
Loading…
Reference in a new issue