iterateTrail :: Eval.Trail CodeDbId
             -> (Eval.Trail CodeDbId -> Either [Error] (Eval.Trailing CodeDbId (Eval.Val CodeDbId)))
             -> Either [Error] (Eval.Val CodeDbId)
iterateTrail trail1 next =
  do (Eval.Trailing newTrail result) <- next trail1
     let mergedTrails = Set.union trail1 newTrail
     if trail1 == mergedTrails
       then pure result
       else iterateTrail mergedTrails next
iterateTrail :: Eval.Trail CodeDbId
             -> (Eval.Trail CodeDbId -> Either [Error] (Eval.Trailing CodeDbId (Eval.Val CodeDbId)))
             -> Either [Error] (Eval.Val CodeDbId)
iterateTrail trail1 next =
  do (Eval.Trailing newTrail result) <- next trail1
     let mergedTrails = Set.union trail1 newTrail
     if trail1 == mergedTrails
       then pure result
       else iterateTrail mergedTrails next
iterateTrail trail1 next =
  do (Eval.Trailing newTrail result) <- next trail1
     let mergedTrails = Set.union trail1 newTrail
     if trail1 == mergedTrails
       then pure result
       else iterateTrail mergedTrails next