Last active
March 27, 2025 02:07
-
-
Save lagenorhynque/a5ec8cd8c04b61e8e6658f462b99efc6 to your computer and use it in GitHub Desktop.
Reimplementation of typical higher-order functions in Clojure, Elixir, Scala and Haskell
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(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]) | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
ref. https://github.com/fpinscala/fpinscala/blob/second-edition/src/main/scala/fpinscala/answers/datastructures/List.scala