Skip to content

Instantly share code, notes, and snippets.

@ntreu14
Last active December 18, 2018 22:12
Show Gist options
  • Save ntreu14/38ce606c3212364c76312e63a418a107 to your computer and use it in GitHub Desktop.
Save ntreu14/38ce606c3212364c76312e63a418a107 to your computer and use it in GitHub Desktop.
Cons list in F#
namespace ConsList
module List =
type 'a List =
| Nil
| Cons of ('a * 'a List)
let private asCons v = Cons (v, Nil)
let rec map f = function
| Nil -> Nil
| Cons (v, rest) -> Cons (f v, map f rest)
let rec iter action = function
| Nil -> ()
| Cons (v, rest) -> action v; iter action rest
let rec filter predicate = function
| Nil -> Nil
| Cons (v, rest) ->
if predicate v
then filter predicate <| Cons (v, rest)
else filter predicate rest
let rec fold folder state = function
| Nil -> state
| Cons (v, rest) -> fold folder (folder state v) rest
let rec append xs ys =
match xs with
| Nil -> ys
| Cons (v, rest) -> Cons (v, append rest ys)
let concat xs = xs |> fold append Nil
let collect f = concat << map f
let rec choose f = function
| Nil -> Nil
| Cons (v, rest) ->
match f v with
| Some x -> Cons (x, choose f rest)
| None -> choose f rest
let rec reverse = function
| Nil -> Nil
| Cons (v, rest) -> append (reverse rest) <| Cons (v, Nil)
let rec reduce reducer = function
| Nil -> invalidArg "[| |]" "Cannot pass in an empty array"
| Cons (head, rest) -> fold reducer head rest
let isEmpty = function
| Nil -> true
| _ -> false
let head = function
| Nil -> invalidArg "Nil" "Cannot get head of Nil."
| Cons (head, _) -> head
let tail = function
| Nil -> invalidArg "Nil" "Cannot get tail of Nil."
| Cons (_, rest) -> rest
let scan folder state =
fold
(fun a b -> append (folder (head a) b |> asCons) (tail a))
(asCons state)
let inline sum list = reduce (+) list
let inline sumBy f = sum << map f
let exists predicate =
filter predicate >> isEmpty >> not
let contains x =
exists ((=) x)
let rec tryFind predicate = function
| Nil -> None
| Cons (v, rest) ->
if predicate v
then Some v
else tryFind predicate rest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment