【发布时间】:2019-04-08 13:26:20
【问题描述】:
Daniel Wagner 的comment 让我想到了这个问题。让我们从过度简化开始。假设你有一个类型
data Foo a = Foo [a]
然后你可以写Functor实例
instance Functor Foo where
fmap f (Foo l) = Foo (fmap f l)
你可以把右边改写为
Foo . fmap f $ l
认识到(->) a,fmap = (.),你可以写它
fmap Foo (fmap f) l
重复,你得到
fmap (fmap Foo) fmap f l
所以,最后,
fmap f (Foo l) =
fmap fmap fmap Foo fmap f l
如果你选择一个稍微复杂一点的函子呢?
data Bar = Bar [Maybe a]
instance Functor Bar where
fmap f (Bar l) = Bar (fmap (fmap f) l)
我开始手动操作,但它开始失控,所以我切换到自动。
infixl 9 :@
data Expr
= BAR | F | L | FMap | Expr :@ Expr
deriving (Show)
rewrite :: Expr -> Expr
rewrite (p :@ (q :@ r))
= rewrite $ FMap :@ p :@ q :@ r
rewrite (p :@ q) = rewrite p :@ q
rewrite e = e
main = print $ rewrite $
BAR :@ (FMap :@ (FMap :@ F) :@ L)
不幸的是,这似乎产生了非常巨大的结果。我什至无法在合理的时间内计算出树最左边的叶子。这到底是个多大的表情?随着更多仿函数的分层,它的增长速度有多快?
【问题讨论】:
标签: haskell