对于类型对齐的序列,我如何用foldMap表示foldr?

时间:2015-06-22 16:23:04

标签: haskell types monoids type-variables foldable

我正在玩How to avoid using Select in Excel VBA macros,特别是我正在弄乱折叠它们的想法。可折叠的类型对齐序列如下所示:

class FoldableTA fm where
  foldMapTA :: Category h =>
                (forall b c . a b c -> h b c) ->
                fm a b d -> h b d
  foldrTA :: (forall b c d . a c d -> h b c -> h b d) ->
             h p q -> fm a q r -> h p r
  foldlTA :: ...

通过首先使用foldrTA以天真的方式将序列转换为类型对齐列表,可以很容易地在foldMapTA方面实现foldMapTA(即,使用类型对齐列表类别)然后折叠该列表。不幸的是,这可能是非常低效的,因为长列表可以预先设置为短列表。我一直试图找出一种方法来使用类似于Data.Foldable中使用的技巧来更有效地定义右侧和左侧折叠,但这些类型让我头晕目眩。 Endo似乎不够通用,我从其他方向采取的每一步都会让我找到比我能追踪的更多类型变量。

1 个答案:

答案 0 :(得分:7)

我发现这个类型检查:

{-# LANGUAGE RankNTypes #-}
module FoldableTA where

import Control.Category
import Prelude hiding (id, (.))

class FoldableTA fm where
  foldMapTA :: Category h => (forall b c . a b c -> h b c) -> fm a b d -> h b d
  foldrTA :: (forall b c d . a c d -> h b c -> h b d) -> h p q -> fm a q r -> h p r
  foldrTA f z t = appEndoTA (foldMapTA (\x -> TAEndo (f x)) t) z

newtype TAEndo h c d = TAEndo { appEndoTA :: forall b. h b c -> h b d  }

instance Category (TAEndo h) where
    id = TAEndo id
    TAEndo f1 . TAEndo f2 = TAEndo (f1 . f2)

不知道它是否有意义,但是有这么多的类型索引,我怀疑有很多类型检查代码 没有意义。