Open jackfirth opened 7 years ago
Let's look at the types. For example, Op r a
is a newtype wrapper around a -> r
. So if we put Op r
instead of f
, we get
(a -> f a) -> f a === (a -> a -> r) -> a -> r
which is basically join @(->)
.
I'm not really sure how it should work for things like Equivalence
or Comparison
, though.
I've run into this in a handful of cases where I've got a contravariant applicative and I want to "map it over" a list (more accurately an indexable container like a vector). This mapping ends up depending on the length of the list, as the logic goes like so:
f a
v a
withsize :: v a -> Int
and a partialref :: v a -> Int -> a
functioncontramap
to take an index and convertf a
tof (v a)
, where it only operates on the element at the index and ignores the othersf a
in a way that's just repeatedly applyingdivide
withconquer
as the empty casef (v a)
that operates on the elements at those indexesf (v a)
that gets the size of the input container, uses that size to construct a list of all indexes inv a
, constructs a combinedf (v a)
operating on the elements at those indexes, then applies that combinedf (v a)
to the input containerf
that lets me turn anya -> f a
function into anf a
I'm not sure if this something that
Decidable
can do or if the only reason usingDecidable
seems unintuitive to me is because of the partial nature of theref
function. For context, I mostly work with impure functional languages so a constant-time partialref
function is more idiomatic than it would be in Haskell.