<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    On 2017-07-21 17:57, Kim-Ee Yeoh wrote:<br>
    <blockquote
cite="mid:CAPY+ZdQbVV+n2j3e1GCCD4GpmRCRs1k2UkkM_-jCj5dKy-aKvg@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div>Another perfectly cromulent definition is:</div>
        <div><br>
        </div>
        <div>untilNothing f = fromJust . last . takeWhile isJust .
          iterate (f =<<) . Just</div>
        <div><br>
        </div>
        <div>This has 2 advantages:</div>
        <div><br>
        </div>
        <div>1. It illustrates the haskellism that "A list is a loop is
          a list."</div>
        <div>2. It composes much-beloved list combinators into a
          reasonable pipeline.</div>
      </div>
    </blockquote>
    <p>Note that</p>
    <p>
    </p>
    <pre> fromJust . last . takeWhile isJust . iterate (f =<<) . Just
        ≡
        last . catMaybes . takeWhile isJust . iterate (f =<<) . Just
</pre>
    <p>Note further that that with <tt>duplicate x = (x,x)</tt>,<br>
    </p>
    <pre> \initialElement -> catMaybes . takeWhile isJust . iterate (f =<<) . Just $ initialElement
        ≡
        \initialElement -> initialElement: unfoldr (fmap duplicate . f) initialElement
</pre>
    <p>In other words, the pipeline is basically equivalent to a simple
      <tt>unfoldr</tt> modulo the first step. Therefore,<br>
    </p>
    <pre> untilNothing f initialElement = last $ initialElement : unfoldr (fmap duplicate . f) initialElement
</pre>
    <p>Which reveals the relation to anamorphisms and makes it possible
      to drop two of the three pain-inducing functions (<tt>isJust</tt>
      and <tt>fromJust</tt>).</p>
    <p>This further hints at the fact that loops are a combination of
      anamorphisms/unfolds (here: <tt>unfoldr</tt>) and
      catamorphisms/folds (here: <tt>last</tt>). As <tt>last</tt> can
      easily be replaced with better options like <tt>foldMap Last</tt>,
      the search for a "better" implementation should basically consist
      of a search for a more suitable unfold. A simple hoogle seems to
      reveal several options.</p>
    <p><br>
      Cheers,<br>
      MarLinn</p>
    <p>PS: The relation to lists still remains in my version, but it may
      be easier to see that the "haskellism" is just an unfortunate
      result of both their prominence in the standard libraries and the
      specialised syntax we have for them. That's why it's a
      "haskellism", and not a universal relation.</p>
  </body>
</html>