I’ve just noticed that you can do many of the things you advertise also with the lattices package, e.g.:
import Algebra.Lattice
import qualified Data.Set as S
import qualified Data.Map as M
transitive g =
lfpFrom g $ \sets ->
M.mapWithKey
(\v vs -> S.insert v (S.unions [ sets M.! v' | v' <- S.toList vs ]))
sets
main = print $ transitive
$ M.map S.fromList $ M.fromList [(1,[2,3]),(2,[1,3]),(3,[])]
I guess your package has the advantage of allowing more natural code. But it requires using custom functions like rInsert and the R type wrapper, so I’m not sure which is easier to use.
I guess performance is another advantage of your approach.
Thanks for the pointer, I was not aware of that package!
Would it be fair to say that rec-def is to lattice’s lfpFrom as expressing recursion with let is to using fix?
But it requires using custom functions like rInsert
True! That is so because I want Data.Recursive.Set to provide a safe interface, and only expose monotonic functions. An alternative interface allowing (lifting of) arbitrary functions is possible as well, but would be a bit less safe.
Well spotted! Does it happen with -fpedantic-bottoms as well? By default GHC thinks its fine to optimize non-terminating into terminating ones here, which would explain this.
I expect it will be hard to predict termination when you use this in larger programs.
Fair criticism! But is it harder than applying other knot-tying tricks, where you need to ensure sharing actually happens? (I’m definitely not claiming that it’s easier than that…)
Without optimization, this program takes very long (not quite bottom, but effectively bottom); with optimizations it is almost instant:
$ ghc --make Test ; timeout -v 10s ./Test
timeout: sending signal TERM to command ‘./Test’
$ ghc -O --make Test ; timeout -v 10s ./Test
817770325994397771
Of course, the unoptimized is not really bottom in the formal sense – with enough time and memory, it will finish. But in a more pragmatic sense it “doesn’t work”, and GHC’s optimization makes it work.
(I’m sure you know that; this is more for the record.)