Created
April 5, 2022 13:34
-
-
Save jship/80ebec26eeebed6697484c16031d3459 to your computer and use it in GitHub Desktop.
Neat example of value recursion, courtesy of @tstat
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- | 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