Created
June 29, 2017 14:05
-
-
Save robrix/3ecbf3da4b48f6deac9f5b8520d07f68 to your computer and use it in GitHub Desktop.
Functions defined with fix are more composable than directly recursive functions
This file contains 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
module ParameterizedRecursion where | |
import Data.Function | |
-- A recursive function… | |
showTable :: (Show a, Show b) => [(a, b)] -> String | |
showTable ((a, b) : rest) = show a ++ " | " ++ show b ++ "\n" ++ showTable rest | |
showTable [] = "" | |
-- …can be defined instead as a fixpoint… | |
showTableFix :: (Show a, Show b) => [(a, b)] -> String | |
showTableFix = fix showTableNonRec | |
-- …of a nonrecursive function… | |
showTableNonRec :: (Show a, Show b) => ([(a, b)] -> String) -> [(a, b)] -> String | |
showTableNonRec recur ((a, b) : rest) = show a ++ " | " ++ show b ++ "\n" ++ recur rest | |
showTableNonRec _ [] = "" | |
-- …which we can use to vary the behaviour arbitrarily at any iteration… | |
showTableN :: (Show a, Show b) => Int -> [(a, b)] -> String | |
showTableN 0 = const "" | |
showTableN n = showTableNonRec (showTableN (pred n)) | |
-- …or even write as combinators encoding these variations… | |
nThenDefault :: ((a -> b) -> a -> b) -> b -> Int -> a -> b | |
nThenDefault f defaultB = go | |
where go 0 = const defaultB | |
go n = f (go (pred n)) | |
-- …which we then compose with the nonrecursive function. | |
showTableNComposed :: (Show a, Show b) => Int -> [(a, b)] -> String | |
showTableNComposed = nThenDefault showTableNonRec "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment