To detect a cycle, use two pointers: slow moves one step per iteration, fast moves two steps. This is the tortoise and hare technique. If there is a cycle, fast will eventually lap slow inside the cycle. When they meet, you have confirmed a cycle exists.
The meeting point depends on cycle length and tail length. This uses space instead of for a visited set. You do not need to store anything except the two pointers. The algorithm is simple and works for any functional graph.