Skip to content

Instantly share code, notes, and snippets.

@jship
Created April 5, 2022 13:34
Show Gist options
  • Save jship/80ebec26eeebed6697484c16031d3459 to your computer and use it in GitHub Desktop.
Save jship/80ebec26eeebed6697484c16031d3459 to your computer and use it in GitHub Desktop.
Neat example of value recursion, courtesy of @tstat
-- | Maps each element of a list to a three-element tuple where the
-- first element is the previous element in the input list and the
-- final element is the next element of the input list.
--
-- > tangle [1..4]
-- [(4,1,2),(1,2,3),(2,3,4),(3,4,1)]
--
tangle :: forall a. [a] -> [(a, a, a)]
tangle = \input ->
case input of
[] -> []
firstElementOfInput : xs ->
-- go returns the last element of the input list. We pass this
-- into go as the previous element for the first element in the
-- list.
--
-- The first element of the list is passed through recursive
-- calls to go until we reach the last element of the list. The
-- "next" element of the last entry in the list is the first
-- element of the input list.
let (lastElemOfInput, tangledList) = go firstElementOfInput lastElemOfInput input
in tangledList
where
go
:: a -- ^ first element of input list
-> a -- ^ previous element of input list
-> [a] -- ^ input list
->
( a -- ^ last element of input
, [(a, a, a)] -- ^ tangled list
)
go firstElem predElem xs0 =
case xs0 of
[x] -> (x, [(predElem, x, firstElem)])
x:xs ->
let curr = (predElem, x, nextElem) : rest
nextElem = case rest of
(_, y, _):_ -> y
(lastElemOfInput, rest) = go firstElem x xs
in (lastElemOfInput, curr)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment