import * as Reader from 'fp-ts/lib/Reader'; | |
import { RouteData } from 'helpers/routes/types'; | |
import { pipe, pipeWith } from 'pipe-ts'; | |
// This will soon be part of fp-ts core | |
// https://github.com/gcanti/fp-ts/issues/904#issuecomment-619346296 | |
const chainW: <Q, A, B>( | |
f: (a: A) => Reader.Reader<Q, B>, | |
) => <R>(ma: Reader.Reader<R, A>) => Reader.Reader<R & Q, B> = Reader.chain as Unrestricted; | |
{ | |
const renderCopyright = RouteData.match({ | |
Search: () => 'unsplash search copyright goes here', | |
default: () => 'unsplash copyright goes here', | |
}); | |
// ✅ doesn't care about child deps (routeData) | |
const renderFooter = (year: number) => | |
pipe(renderCopyright, copyright => `<footer>${copyright} ${year}</footer>`); | |
// ❌ does care about child deps (year) | |
const renderPage = (hideFooter: boolean) => ({ year }: { year: number }) => { | |
if (hideFooter) { | |
return () => '<body>No Footer.</body>'; | |
} else { | |
return pipe(renderFooter(year), footer => `<body>${footer}</body>`); | |
} | |
}; | |
// ❌ does care about child deps (year and routeData) | |
// ❌ has to manually aggregate child deps | |
const wrapWithHtml = ({ year, routeData }: { year: number; routeData: RouteData }) => | |
pipeWith(renderPage(true)({ year })(routeData), page => `<html>${page}</html>`); | |
declare const routeData: RouteData; | |
wrapWithHtml({ year: 2014, routeData }); | |
} | |
{ | |
const renderCopyright = ({ routeData }: { routeData: RouteData }) => | |
RouteData.match(routeData, { | |
Search: () => 'unsplash search copyright goes here', | |
default: () => 'unsplash copyright goes here', | |
}); | |
// ✅ doesn't care about child deps (routeData) | |
const renderFooter = pipeWith( | |
renderCopyright, | |
chainW(copyright => ({ year }: { year: number }) => `<footer>${copyright} ${year}</footer>`), | |
); | |
// ✅ doesn't care about child deps (year and routeData) | |
const renderPage = (hideFooter: boolean) => { | |
if (hideFooter) { | |
return Reader.of('<body>No Footer.</body>'); | |
} else { | |
return pipeWith( | |
renderFooter, | |
Reader.map(footer => `<body>${footer}</body>`), | |
); | |
} | |
}; | |
// ✅ doesn't care about child deps (year and routeData) | |
const wrapWithHtml = pipeWith( | |
renderPage(true), | |
Reader.map(page => `<html>${page}</html>`), | |
); | |
declare const routeData: RouteData; | |
wrapWithHtml({ year: 2014, routeData }); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment