簡體   English   中英

廣義的“折疊”或如何一次執行“折疊”和“地圖”

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

(通過標題道歉,我不能做得更好)

我的問題是找到一些通用的結構或“標准”函數來執行下一件事:

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

那么,我們不僅可以映射元素,還可以映射整個結構。

一些(不是真實的)例子

xmap id myBinaryTree :: [a]

目前,我必須做一個顯式的結構轉換(典型的fromListtoList

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

(執行toStructfromStruct我使用fold )。

存在某種方式來推廣to / from結構? (應該)存在該功能( xmap )?

謝謝!! :)

由於fg是仿函數,因此您正在尋找自然變換 (另請參閱“ 您可以定義自然變換” )。 所以轉型就好

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

需要創建xmap然后才是

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

你仍然需要定義(f :~> g) ,但是沒有一般的方法。

我想補充一下tel的答案 (我只是在閱讀之后得到了我的想法),在許多情況下,你可以進行一般自然變換,它將與foldMap類似。 如果我們可以使用foldMap ,我們知道fFoldable 然后我們需要一些方法來構建ga元素並將它們組合在一起。 我們可以使用Alternative ,它有我們需要的所有( pureempty<|> ),雖然我們也可以為此目的構造一些不太通用的類型類(我們不需要<*>任何地方)。

{-# 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

然后使用tel的xmap

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

我們可以做的事情

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM