VSL - The prelude.list Structure
# Copyright 2011 Petter Urkedal
#
# This file is part of the Viz Standard Library <http://www.vizlang.org/>.
#
# The Viz Standard Library (VSL) is free software: you can redistribute it
# and/or modify it under the terms of the GNU Lesser General Public License as
# published by the Free Software Foundation, either version 3 of the License,
# or (at your option) any later version.
#
# The VSL is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
# more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the VSL. If not, see <http://www.gnu.org/licenses/>.
open prereq
open effect
#?ffoc type t α := list α
#?ffoc {#
type t α
inj [] : t α
inj [;] : α → t α → t α
#?ffoc #}
let init n f
let loop n zs
if n = 0 be zs
else be loop (n - 1) [f (n - 1); zs]
be loop n []
let head at [] fail "An empty list was passed to list.head."
at [x; _] be x
let tail at [] fail "An empty list was passed to list.tail."
at [_; xs] be xs
let nth i
at [] be none
at [x; xs] be i = 0 ⇒ some x; nth (i - 1) xs
let fold f
at [] be ident
at [x; xs] be fold f xs ∘ f x
let foldr f xs be fold f (rev xs)
let fold2 f
at [], [] be ident
at [], _ fail "fold2: left list is smaller."
at _, [] fail "fold2: right list is smaller."
at [x; xs], [y; ys] be fold2 f (xs, ys) ∘ f (x, y)
let iter f
at [] be return ()
at [x; xs] be f x >> iter f xs
let for_all f
at [] be true
at [x; xs] be f x ∧ for_all f xs
let for_some f
at [] be false
at [x; xs] be f x ∨ for_some f xs
let count f
let add_count n
at [] be n
at [x; xs] be add_count (f x ⇒ n + 1; n) xs
be add_count 0
let length xs
let add_length n
at [] be n
at [x; xs] be add_length (n + 1) xs
be add_length 0 xs
let find f
at [] be none
at [x; xs] if f x be some x
else be find f xs
let filter f
let loop zs
at [] be rev zs
at [x; xs] if f x be loop [x; zs] xs
else be loop zs xs
be loop []
let bifilter f
let loop xs ys
at [] be (rev xs, rev ys)
at [z; zs] if f z be loop [z; xs] ys zs
else be loop xs [z; ys] zs
be loop [] []
let drop_while f
at [] be []
at [x; xs] if f x be drop_while f xs
else be [x; xs]
let take_while f xs
let loop zs
at [] be xs
at [y; ys] if f y be loop [y; zs] ys
else be rev zs
be loop [] xs
let mapr f
let loop ys
at [] be ys
at [x; xs] be loop [f x; ys] xs
be loop []
let map f xs be rev (mapr f xs)
let mapi f
let loop i zs
at [] be rev zs
at [x; xs] be loop (i + 1) [f i x; zs] xs
be loop 0 []
let catr xs ys
be that xs which
at [] be ys
at [x; xs] be catr xs [x; ys]
let rev xs be catr xs []
let cat xs ys be catr (rev xs) ys
let flatten
at [] be []
at [xs] be xs
at [xs; xss] be cat xs (flatten xss)
let zip (xs, ys)
let loop zs
at [x; xs]
at [y; ys] be loop [(x, y); zs] xs ys
at [] fail "list.zip: The first list is longer than the second."
at []
at [] be rev zs
at _ fail "list.zip: The second list is longer than the first."
be loop [] xs ys
let zip_trunc (xs, ys)
let loop zs
at [x; xs] at [y; ys] be loop [(x, y); zs] xs ys
at [] be rev zs
at [] at _ be rev zs
be loop [] xs ys
let unzip zs
let loop xs ys
at [(x, y); zs] be loop [x; xs] [y; ys] zs
at [] be (rev xs, rev ys)
be loop [] [] zs