getValue('#comment')which is an action which retrieves text on an element. Now, it might error finding the element or the value string may not exist so it returns
Task Error (Maybe String). After that, we must
mapover both the
Maybeto pass our text to
validate, which in turn, gives us back
String. Then onto mapping for days to send the
Stringin our current
Task Error (Maybe (Either ValidationError String))into
postCommentwhich returns our resulting
joina few, homogenize them, deconstruct them, and so on. In this chapter, we'll focus on homogenizing them via natural transformations.
(Functor f, Functor g) => f a -> g a. What makes it special is that we cannot, for any reason, peek at the contents of our functor. Think of it as an exchange of highly classified information - the two parties oblivious to what's in the sealed manila envelope stamped "top secret". This is a structural operation. A functorial costume change. Formally, a natural transformation is any function for which the following holds:
mapthen run our natural transformation and get the same result. Incidentally, that follows from a free theorem though natural transformations (and functors) are not limited to functions on types.
Numbers). The difference here is simply that we're working with algebraic containers and we have some theory at our disposal.
mapdoesn't get lost in the shape shift shuffle. That is the whole point:
mapmust carry on, according to our definition, even after the transformation.
ioToTaskas converting synchronous to asynchronous or
taskToIO- that would be a supernatural transformation.
List. Natural transformations provide a nice way to convert to the target type knowing our
mapwill be sound.
arrayToList, and voilà! Our
List aand we can
sortByif we please.
map(f)to the left of natural transformation as shown in
Taskare isomorphic. We can also write a
listToArrayto complement our
arrayToListand show that they are too. As a counter example,
arrayToMaybeis not an isomorphism since it loses information:
mapon either side yields the same result. I mention isomorphisms here, mid-chapter while we're on the subject, but don't let that fool you, they are an enormously powerful and pervasive concept. Anyways, let's move on.
head :: [a] -> acan be viewed as
head :: [a] -> Identity a. We are free to insert
Identitywherever we please whilst proving laws since we can, in turn, prove that
ais isomorphic to
Identity a(see, I told you isomorphisms were pervasive).
chain(eitherToTask). Both have the same effect; they naturally transform the functor our
Taskis holding into another
jointhe two. Like pigeon spikes on a window ledge, we avoid nesting right at the source. As they say in the city of light, "Mieux vaut prévenir que guérir" - an ounce of prevention is worth a pound of cure.
Taskin most cases).
Either b ato
findNameByIdto remove the nested