ink, 370 369369 354 bytes
LIST B=fly,spider,bird,cat,dog,horse
~temp t=" to{s} a "
VAR s=" swallow"
-(i)~B=B(i)
There was an old lady who{s}ed a {B}{.|,}
{|That wriggled and iggled and jiggled inside her|How absurd|Imagine that|What a hog|She died of course.->END}{|{.| to{ts} a {B}}.}
-(k)~B--
{B:
She{s}ed the {B+1} to catch the {B},
->k
}I don't know why she{s}ed that fly,
Perhaps she'll die.
\
->i
Try it online!Try it online!
LIST B=fly,spider,bird,cat,dog,horse // Ink's "LIST"s aren't much like lists - they're more like enums. Here we create a list type stating what animals exist, and make a set containing none of them.
~temp t=" to{s} a " // Pretty self-explanatory. Uses a local variable, because globals can't have variable expansions in them.
VAR s=" swallow " // All global variables are defined before anything else happens, so the line above can actually access thisPretty valueself-explanatory
-(i)~B=B(i) // The i label keeps track of how many times we've visited it. We set B (the set) to be equal to the i-th item in B (the list type).
There was an old lady who{s}ed a {B}{.|,} // Print the first line. {.|,} is a sequence - it's a period the first time it's encountered, and a comma every subsequent time.
// Sequences can have more than one item in them, which is how we print the second line. When we get to the horse one, we terminate the program right away.
{|That wriggled and iggled and jiggled inside her|How absurd|Imagine that|What a hog|She died of course.->END}{|{|.|to{ts} a {B}}.}
-(k)~B-- // Step back through the list type.
{B: // A conditional - we execure the next two lines if B is non-empty.
She{s}ed the {B+1} to catch the {B}, // Print the "she swallowed the..." line
->k // And repeat
}I don't know why she{s}ed that fly, // Only reached when the conditional fails.
Perhaps she'll die.
\ // A backslash and a space to force an empty line.
->i // Back to the top