Well suppose you define such a graph
data Graph a = Node a [Graph a]
Then fmap defined exactly as you would expect
instance Functor Graph where fmap f (Node a ns) = Node (fa) (map (fmap f) ns)
Now, if there is a loop, we would have to do something like
foo = Node 1 [bar] bar = Node 2 [foo]
Now fmap is lazy enough that you can evaluate part of its result without forcing the rest of the calculations, so it works as well as any node-related graph representation!
In general, this is a trick: fmap lazy, so you can handle it the same way you handle any non-inductive values ​​in Haskell (: carefully).
In addition, you must define fmap against random other functions, since
fmap is a good, well-known API with rules- There are things waiting for
Functor s in your container - You can abstract the other bits of your program so that they depend on the
Functor and not on your schedule.
In general, when I see that something is a functor, I think: “Ah, great, I know how to use it,” and when I see
superAwesomeTraversal :: (a -> b) -> Foo a -> Foo b
I'm a little worried that this will do unexpected things.
source share