Skip to content

Instantly share code, notes, and snippets.

@lagenorhynque
Last active March 27, 2025 02:07
Show Gist options
  • Save lagenorhynque/a5ec8cd8c04b61e8e6658f462b99efc6 to your computer and use it in GitHub Desktop.
Save lagenorhynque/a5ec8cd8c04b61e8e6658f462b99efc6 to your computer and use it in GitHub Desktop.
Reimplementation of typical higher-order functions in Clojure, Elixir, Scala and Haskell
(ns my-prelude
(:refer-clojure :exclude [filter map reduce reverse]))
(defn reduce' [f val coll]
(if (empty? coll)
val
(recur f (f val (first coll)) (rest coll))))
(defn reverse' [coll]
(reduce' #(cons %2 %1) () coll))
(defn map' [f coll]
(reduce' #(cons (f %2) %1)
()
(reverse' coll)))
(defn filter' [pred coll]
(reduce' (fn [acc x] (if (pred x) (cons x acc) acc))
()
(reverse' coll)))
(comment
(reduce' * 1 [1 2 3 4 5])
(map' #(* % %) [1 2 3 4 5])
(filter' odd? [1, 2, 3, 4, 5])
)
defmodule MyPrelude do
def reduce([], acc, _), do: acc
def reduce([x | xs], acc, f),
do: reduce(xs, f.(acc, x), f)
def reverse(list),
do: reduce(list, [], &([&2 | &1]))
def map(list, f),
do: reduce(reverse(list), [], &([f.(&2) | &1]))
def filter(list, pred),
do: reduce(reverse(list), [], fn acc, x ->
if pred.(x), do: [x | acc], else: acc
end)
end
module MyPrelude where
import Prelude hiding (filter, foldl, foldr, map, reverse)
foldLeft :: (b -> a -> b) -> b -> [a] -> b
foldLeft _ acc [] = acc
foldLeft f acc (x:xs) = foldLeft f (f acc x) xs
reverse' :: [a] -> [a]
reverse' = foldLeft (flip (:)) []
map' :: (a -> b) -> [a] -> [b]
map' f = foldLeft (\acc x -> f x : acc) [] . reverse'
filter' :: (a -> Bool) -> [a] -> [a]
filter' pred = foldLeft (\acc x -> if pred x then x : acc else acc) [] . reverse'
object MyPrelude:
def foldLeft[A, B](list: List[A])(acc: B)(f: (B, A) => B): B =
if (list.isEmpty) acc
else foldLeft(list.tail)(f(acc, list.head))(f)
def reverse[A](list: List[A]): List[A] =
foldLeft(list)(List())((acc, x) => x :: acc)
def map[A, B](list: List[A])(f: A => B): List[B] =
foldLeft(reverse(list))(List())((acc, x) => f(x) :: acc)
def filter[A](list: List[A])(pred: A => Boolean): List[A] =
foldLeft(reverse(list))(List())((acc, x) => if (pred(x)) x :: acc else acc)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment