Hi David,
The great news is that Shake is not file-specific in any way, so
depending on things that aren't files is no harder. Your use case
seems to make sense for Shake. There are two different approaches to
take:
1) Have each AMI also have some file on disk, containing whatever you
think is the "representative value" (e.g. a timestamp). Now you depend
on files, and use files to represent AMIs. The key things here are
that Shake allows you to have a rule run and not update the file, plus
the monadic dependencies, makes this properly equivalent to really
encoding AMI values.
2) Write your own type of rule that really does talk about AMI values.
The module for writing your own rules is
https://hackage.haskell.org/package/shake-0.15.5/docs/Development-Shake-Rule.html.
You basically define a type for AMI keys (names I guess?) and AMI
values (modified timestamps, hashes - whatever changes whenever an AMI
itself changes). You define a Rule instance which gives you a way to
calculate a storedValue. It's then typical to write some
strongly-typed wrappers over rule and apply, which give you the
interface most people are used to.
If your rule type is a bit simpler, you might even get away with Oracles.
Thanks, Neil