【问题标题】:What is a "applicative transformation" in naturality of traversability?什么是可遍历性的“应用转换”?
【发布时间】:2017-12-28 02:09:17
【问题描述】:

Traversable 类中的 traversesequenceA 函数必须满足以下“自然性”定律:

t . traverse f == traverse (t . f)
t . sequenceA == sequenceA . fmap t

对于每个“应用转换”t。但它是什么?

instance Traversable [] 似乎不适用于 t = tail

Prelude> tail . sequenceA $ [[1],[2,3]]
[[1,3]]
Prelude> sequenceA . fmap tail $ [[1],[2,3]]
[]

t = join (++) 也不是(重复列表两次):

Prelude Control.Monad> join (++) . sequenceA $ [[1],[2,3]]
[[1,2],[1,3],[1,2],[1,3]]
Prelude Control.Monad> sequenceA . fmap (join (++)) $ [[1],[2,3]]
[[1,2],[1,3],[1,2],[1,3],[1,2],[1,3],[1,2],[1,3]]

那么t他们对什么感到满意?

【问题讨论】:

  • Data.Traversable 文档中要注意的另一件事是“参数化隐含了自然法则”。这基本上意味着任何通过类型检查器的traverse 的定义都将遵守自然法则;你不必担心。

标签: haskell applicative traversable


【解决方案1】:

Data.Traversable 的 Hackage 页面定义了一个应用转换,如下所示。

[A]n 应用变换是一个函数

t :: (Applicative f, Applicative g) => f a -> g a

保留 Applicative 操作,即

t (pure x) = pure x

t (x <*> y) = t x <*> t y

最简单的例子就是恒等函数。 id 是一个应用转换。更具体的列表示例是 reverse

reverse (pure x) = reverse [x] = [x] = pure x
-- (the (<*>) law is more difficult to show)

您可以在 GHCi 中验证您引用的法律是否适用于 reverse

Prelude> reverse . sequenceA $ [[1], [2,3]]
[[1,3],[1,2]]
Prelude> sequenceA . fmap reverse $ [[1], [2,3]]
[[1,3],[1,2]]

来源:Data.Traversable

【讨论】:

  • &lt;*&gt;法则更难正式表达,但如果用concatmap来表达,我想至少直观上会变得清晰。基本原理是concat (reverse (map reverse xss)) = reverse (concat xss)。看几个小例子应该让任何人相信这是真的。例如reverse (concat [[1,2], [3,4,5]]) = [5,4,3,2,1] = concat [[5,4,3], [2,1]] = concat (reverse (map reverse [[1,2], [3,4,5]]))
猜你喜欢
  • 1970-01-01
  • 2012-02-01
  • 2019-09-19
  • 1970-01-01
  • 2021-12-17
  • 1970-01-01
  • 1970-01-01
  • 2010-11-14
  • 2012-06-05
相关资源
最近更新 更多