How do I write the Traversable instance for ((->) a)
?
I think I could do it, if I could generically unwrap an Applicative Functor:
instance Traversable ((->) k) where
-- traverse :: (a -> f b) -> (k -> a) -> f (k -> b)
-- traverse h t = ?
-- h :: Applicative f => a -> f b
-- t :: k -> a
-- h . t :: k -> f b
-- unwrap . h . t :: k -> b
-- pure $ unwrap . h . t :: f (k -> b)
traverse h t = pure $ unwrap . h . t
unwrap :: (Functor f, Applicative f) => f a -> a
unwrap y@(pure x) = x
But, alas, GHC won't let me get away with that:
Parse error in pattern: pure
Generally there is no such thing as
unwrap
, considerf
being the list functor[]
what shouldunwrap
return for[_, _, _]
or better yet for the empty list[]
? Similar thing withMaybe
, supposeh
isconst Nothing
, you would expect to getNothing
. But your line of thought would fail upon trying tounwrap
theNothing
into a valuea
. You can notice that trying to applypure
(to re-pack the result in the functor) means that you expect the result to be alwaysJust
forMaybe
functor, non-empty for[]
etc.There is little hope for
Traversable
instance for a reader functor((->) k)
. While it is not proof, a good evidence in that direction is that such an instance is missing from thePrelude
. Also to traverse a function and produce a final container ([]
orMaybe
) you would need to apply your functionh
to any thinkable output of the function, that is a lot of potential values, in general infinitely many.suppose that
k
isInt
, so the functor isInt ->
, suppose you have a valueg :: Int -> Int
, let it be\n -> if n == 42 then 0 else n
, suppose you wanted to traverse that value with the above function, that traversal would beNothing
ifg
outputs42
for any input, but it doesn't. The traversal cannot know that though (it has no access to the code of the function), so it would have to try all outputs.If
k
were finite, then you could traverse a function by tabulating it. After traversing the table you could possibly produce a result. This may not be what you are after but: