Generalized `fold` or how to perform `fold` and `map` at a time

雨燕双飞 提交于 2019-12-07 06:13:33

问题


(Apology by the title, I can't do better)

My question is to find some generalized struct or "standard" function to perform the next thing:

xmap :: (a -> b) -> f a -> g b

then, we can map not only elements, by also the entire struct.

Some (not real) example

xmap id myBinaryTree :: [a]

at the moment, I must to do a explicit structure conversor (typical fromList, toList) then

toList . fmap id   -- if source struct has map
fmap id . fromList -- if destination struct has map

(to perform toStruct, fromStruct I use fold).

Exists some way to generalize to/from structs? (should be) Exists that function (xmap)?

Thank you!! :)


回答1:


I'd like to add to tel's answer (I got my idea only after reading it) that in many cases you can make general natural transformation that will work similarly to foldMap. If we can use foldMap, we know that f is Foldable. Then we need some way how to constructs elements of g a and combine them together. We can use Alternative for that, it has all we need (pure, empty and <|>), although we could also construct some less general type class for this purpose (we don't need <*> anywhere).

{-# LANGUAGE TypeOperators, RankNTypes #-}
import Prelude hiding (foldr)
import Control.Applicative
import Data.Foldable

type f :~> g = forall a. f a -> g a

nt :: (Functor f, Foldable f, Alternative g) => f :~> g
nt = foldr ((<|>) . pure) empty

Then using tel's xmap

xmap :: (a -> b) -> (f :~> g) -> (f a -> g b)
xmap f n = map f . n

we can do things like

> xmap (+1) nt (Just 1) :: [Int]
[2]



回答2:


As f and g are functors, a natural transformation is what you're looking for (see also You Could Have Defined Natural Transformations). So a transformation like

f :~> g = forall a. f a -> g a 

is needed to create xmap which is then just

xmap :: (a -> b) -> (f :~> g) -> (f a -> g b)
xmap f n = map f . n

You still need to define types of (f :~> g), but there' not a general way of doing that.



来源:https://stackoverflow.com/questions/17834918/generalized-fold-or-how-to-perform-fold-and-map-at-a-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!