base version |
additions |
---|---|
4.8.0.0 | *> <$ <$> <* <*> Applicative Foldable Monoid Traversable Word foldMap mappend mconcat mempty pure sequenceA traverse |
4.9.0.0 | errorWithoutStackTrace |
4.11.0.0 | <> Semigroup |
4.13.0.0 | MonadFail |
Last active
December 8, 2021 21:02
-
-
Save andreasabel/0718ff2b6ca515bba5971748aea6b48f to your computer and use it in GitHub Desktop.
Additions to Haskell's `Prelude` since `base-4.0.0.0`
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
# Andreas Abel, 2021-12-08 | |
# Extract 'since' information for Prelude memebership from sources. | |
# List functions | |
# From https://riptutorial.com/makefile/example/23643/zipping-lists, example: | |
# | |
# func = $1-$2 | |
# | |
# all: | |
# @echo $(call zipWith,func,$(LIST1),$(LIST2)) | |
# | |
tail = $(wordlist 2,$(words $1),$1) | |
zipWith = $(and $(strip $2),$(strip $3),$(call \ | |
$1,$(firstword $2),$(firstword $3)) $(call \ | |
zipWith,$1,$(call tail,$2),$(call tail,$3))) | |
# Variables | |
# working directories | |
dirs = Prelude only-idents word-lists added | |
# base versions | |
versions = \ | |
4.0.0.0 4.1.0.0 4.2.0.0 4.2.0.1 4.2.0.2 \ | |
4.3.0.0 4.3.1.0 4.4.0.0 4.4.1.0 4.5.0.0 4.5.1.0 \ | |
4.6.0.0 4.6.0.1 4.7.0.0 4.7.0.1 4.7.0.2 4.8.0.0 4.8.1.0 4.8.2.0 \ | |
4.9.0.0 4.9.1.0 4.10.0.0 4.10.1.0 4.11.0.0 4.11.1.0 \ | |
4.12.0.0 4.13.0.0 4.14.0.0 4.14.1.0 4.14.2.0 4.14.3.0 \ | |
4.15.0.0 4.16.0.0 | |
# 3.0.3.1 3.0.3.2 ## not useful | |
tailVersions = $(call tail,$(versions)) | |
# Prelude source files from hackage | |
preludes = $(patsubst %,Prelude/%.hs,$(versions)) | |
# Only identifiers left over | |
onlyids = $(patsubst %,only-idents/%.txt,$(versions)) | |
# Flattened to identifier lists | |
wordlists = $(patsubst %,word-lists/%.txt,$(versions)) | |
# Difference to previous version | |
adds = $(patsubst %,added/%.txt,$(tailVersions)) | |
# Commands | |
# onVersionPairs f = zipWith f versions (tail versions) | |
onVersionPairs = $(call zipWith,$1,$(versions),$(tailVersions)) | |
# difference between word lists (only stuff that was added) | |
difference=$(shell comm -13 word-lists/$1.txt word-lists/$2.txt > added/$2.txt) | |
# Goals | |
.PHONY: default | |
default: all | |
.PHONY: all | |
all: $(dirs) fetch strip flatten diff Prelude-additions.md | |
$(dirs) : % : | |
mkdir -p $@ | |
# Getting Prelude source files from hackage | |
.PHONY: fetch | |
fetch: Prelude $(preludes) | |
$(preludes) : Prelude/%.hs : | |
wget -O $@ https://hackage.haskell.org/package/base-$*/src/Prelude.hs | |
# Stripping comments and imports and syntax | |
.PHONY: strip | |
strip: only-idents $(onlyids) | |
# remove | |
# - block comments | |
# - line comments | |
# - preprocessor directives | |
# - 'import' lines | |
# - fixity directives | |
# - type signatures | |
# - keywords and other garbage: 'module' 'Prelude' 'where' 'let 'in' 'vx' | |
# - punctuation: ( , ) = ` .. | |
# - single letter variables and underscores | |
# - qualification | |
$(onlyids) : only-idents/%.txt : Prelude/%.hs Makefile | |
gsed -e '/{-.*-}/d; /{-/,/-}/d; s/--.*//g; /^#/d; /^import/d; /^infix/d; /::/d; s/\<module\>//g; s/\<Prelude\>//g; s/\<where\>//g; s/\<let\>//g; s/\<in\>//g; s/\<vx\>//g; s/(/ /g; s/)/ /g; s/,/ /g; s/=/ /g; s/`/ /g; s/\.\./ /g; s/\<[a-z_]\>//g; s/[A-Z][a-zA-Z]*\.//g;' $< > $@ | |
# Flatten and sort to identifier list | |
.PHONY: flatten | |
flatten: word-lists $(wordlists) | |
# - replace spaces by new lines | |
# - trim | |
# - sort | |
# - remove duplicates, ! | |
$(wordlists) : word-lists/%.txt : only-idents/%.txt # Makefile | |
tr " " "\n" < $< | gsed -e 's/\s+//g; /^\!$$/d;' | sort | uniq > $@ | |
# Difference between word lists | |
.PHONY: diff | |
diff: added $(adds) # Makefile | |
# added/%.txt : word-lists/%.txt | |
$(adds) : $(wordlists) # Makefile | |
$(call onVersionPairs,difference) | |
# Generate report | |
# - for each base version, report identifiers added over previous version | |
# - omit empty lines | |
Prelude-additions.md : $(adds) Makefile | |
echo "# Additions to Haskell's \`Prelude\` since \`base-4.0.0.0\`\n" > $@ | |
echo "| \`base\` version | additions |" >> $@ | |
echo "|---|---|" >> $@ | |
# for ver in $(tailVersions); do if [ -s "added/$$ver.txt" ]; then cat "added/$$ver.txt" | xargs echo -n "| $$ver | " >> $@ ; echo " |" >> $@; fi; done | |
for ver in $(tailVersions); do if [ -s "added/$$ver.txt" ]; then echo "| $$ver | \c" >> $@ ; for id in $$(cat "added/$$ver.txt"); do echo "\`$$id\` \c" >> $@; done; echo "|" >> $@; fi; done | |
# Note: \c suppresses final newline in echo | |
# Debugging | |
.PHONY: debug | |
debug: | |
@echo "versions = $(versions)" | |
@echo "preludes = $(preludes)" | |
@echo "adds = $(adds)" | |
# EOF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The outcome is embarrassing little. Instead of programming the
Makefile
for 2.5 hours, I could have spent 10 minutes to extract the information from https://hackage.haskell.org/package/base-4.16.0.0/changelog.But as people say: Three months in the lab save you one hour in the library.