haskell ZipList可以分发吗?

vqlkdk9b  于 2023-05-18  发布在  其他
关注(0)|答案(1)|浏览(98)

Base提供了ZipList,它只是[]的 Package 器,其中<*>基于zip而不是Cartesian-product。这不是默认的,因为它与Monad []示例不一致,但有些人认为它更直观,而且这两种行为在不同的上下文中都很有用。
Edward Kmett提供了Distributive,它是Traversable的双通道。一个遍历可以Map/推送/分布到任何应用函数中;分配函数可以从任何函子中提取/分解出来。(由于我还没有打开 Package 的原因,distribute不要求外层是适用的。
长度索引列表是分布式的,并且按照您所期望的方式工作。具体来说,他们的Applicationinstance是基于zip *,就像ZipList * 一样!这表明ZipList也可能是Distributive,这将是有用的。
Distributive的文档指出了两件事,任何示例都必须成立:

    • “对于某些x,它[必须]同构于(->) x。"*
  • 列表同构于 partial 函数Int ->
    • “[它]需要有一种方法来一致地压缩可能无限数量的自身副本。
  • 这或多或少就是ZipList的存在理由。

这样够了吗今天下午我花了几个小时试着写instance Distributive ZipList where distributive = ...,但没能让它工作。对于 * 大多数 * 函子f ZipList adistribute f有一个明显的含义,尽管我担心这可能只是因为我没有考虑足够的 * 非 *-可遍历函子。

  • Maybe是棘手的; distribute Nothing应该是[]还是repeat Nothing?但是distributesequenceA的双通道,Traversable Maybe示例说它应该是repeat Nothing
  • (->) e可能是dealbreaker。
  • 直观distribute $ const (repeat x) = repeat (const x)
  • 我们可以将其扩展到任何保证返回无限列表的函数;它看起来有点像(\i -> (! i) <$> f) <$> [0..]
  • 我们可以将 that 扩展到返回有限列表的函数;我们最终得到了一个无限的 * 部分 * 函数列表。我并不认为这是不可接受的部分函数在处理列表时总是出现。
  • 但这意味着distribute $ const [] ≅ repeat undefined,这有点傻。
  • 示例Applicative ZipList包含一个重要的设计决策:length (a <*> b) == min (length a) (length b)(与错误或其他)。我们根本没有利用这一点我可以看到的方式是distribute = const []

有人看到前进的道路吗?
如果偏函数解释是“可接受的”,我们能用任何比distribute f = (\i -> (!! i) <$> f) <$> [0..]更不愚蠢的方式来推广吗?

ymdaylpp

ymdaylpp1#

不,它不可能是分布式的。
PairDistributive示例看起来像这样:

instance Distributive Pair where
    distribute vs = Pair (pFst <$> vs) (pSnd <$> vs)

现在让我们考虑一下列表示例。(我们暂时忽略ZipList噪声,假设基本列表有zippy示例。)我们需要distribute . distribute = id。假设

x = distribute (Pair "" "a")

因此,法律要求:

distribute x = Pair "" "a"

我们可以将distribute的定义替换为Pair,得到:

Pair (pFst <$> x) (pSnd <$> x) = Pair "" "a"

这是一个问题,因为list的(<$>)保留了长度,这里我们要求它在提供相同参数时返回两个不同长度的答案。哎呀!
作为替代方案,你可能会对data Stream a = Cons a (Stream a)感兴趣,这是一种保证无限的列表类型,它 * 可以 * 成为Distributive

sHead :: Stream a -> a
sHead (Cons a _) = a

sTail :: Stream a -> Stream a
sTail (Cons _ as) = as

instance Distributive Stream where
    distribute streams = Cons (sHead <$> streams) (distribute (sTail <$> streams))

相关问题