Skip to content

Instantly share code, notes, and snippets.

@JordanMartinez
Last active March 25, 2022 21:47
Show Gist options
  • Save JordanMartinez/8b4cd9f94df2189ea0ec15c55309911e to your computer and use it in GitHub Desktop.
Save JordanMartinez/8b4cd9f94df2189ea0ec15c55309911e to your computer and use it in GitHub Desktop.
Unfoldable iterateN vs Unfoldable1 iterateN
module Main where
import Prelude
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple(..))
import Effect (Effect)
import Effect.Console (log)
import TryPureScript as TryPureScript
import Data.Unfoldable1 (class Unfoldable1, unfoldr1)
import Data.Unfoldable (class Unfoldable, unfoldr)
import Data.Array.NonEmpty (NonEmptyArray)
main :: Effect Unit
main = TryPureScript.render =<< TryPureScript.withConsole do
log $ show $ ((unfoldableIterateN 4 (_ + 1) 0 ) :: Array Int)
-- Can't use this because NonEmptyArray can't implement Unfoldable
-- log $ show $ ((unfoldableIterateN 4 (_ + 1) 0 ) :: NonEmptyArray Int)
log ""
log $ show $ ((unfoldable1IterateN 0 (_ + 1) 0 ) :: Array Int)
-- Can use it here because NonEmptyArray does implement Unfoldable1
log $ show $ ((unfoldable1IterateN 0 (_ + 1) 0 ) :: NonEmptyArray Int)
unfoldableIterateN :: forall f a. Unfoldable f => Int -> (a -> a) -> a -> f a
unfoldableIterateN n f s = unfoldr go $ Tuple s n
where
go (Tuple x n')
| n' > 0 = Just $ Tuple x $ Tuple (f x) $ n' - 1
| otherwise = Nothing
-- This modification (see *) is required since the loop will always succeed
-- at least once when used with `unfoldr1` whereas `unfoldr`
-- can fail in its first loop.
unfoldable1IterateN :: forall f a. Unfoldable1 f => Int -> (a -> a) -> a -> f a
unfoldable1IterateN n f s = unfoldr1 go $ Tuple s (n - 1) -- * n is subtracted by 1 here
where
go (Tuple x n')
| n' > 0 = Tuple x $ Just $ Tuple (f x) $ n' - 1
| otherwise = Tuple x Nothing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment