Haskell 我怎样才能显示traverse与fmap的交互是明智的?
从直觉上看,以下定律应该成立:Haskell 我怎样才能显示traverse与fmap的交互是明智的?,haskell,traversal,Haskell,Traversal,从直觉上看,以下定律应该成立: traverse f . fmap g = traverse (f . g) 唯一可以直接应用的可遍历的法则是 fmap g = runIdentity . traverse (Identity . g) 这将问题转化为 traverse f . runIdentity . traverse (Identity . g) 唯一的法律,似乎有模糊的正确形状适用于这是自然法。然而,这是关于应用程序转换的,我看不到任何一种 除非我遗漏了什么,否则唯一剩下的就是一个
traverse f . fmap g = traverse (f . g)
唯一可以直接应用的可遍历的法则是
fmap g = runIdentity . traverse (Identity . g)
这将问题转化为
traverse f . runIdentity . traverse (Identity . g)
唯一的法律,似乎有模糊的正确形状适用于这是自然法。然而,这是关于应用程序转换的,我看不到任何一种
除非我遗漏了什么,否则唯一剩下的就是一个参数证明,我还没有得到关于如何编写这些的线索。注意,这个证明实际上是没有必要的,因为所讨论的结果确实是一个自由定理。看
我相信这样做可以:
traverse f . fmap g -- LHS
根据fmap/traverse
法则
traverse f . runIdentity . traverse (Identity . g)
由于Identity
的fmap
实际上是id
runIdentity . fmap (traverse f) . traverse (Identity . g)
Compose
法则提供了一种将两个遍历折叠为一个遍历的方法,但是我们必须首先使用getCompose引入Compose
。Compose=id
runIdentity . getCompose . Compose . fmap (traverse f) . traverse (Identity . g)
-- Composition law:
runIdentity . getCompose . traverse (Compose . fmap f . Identity . g)
再次使用标识
fmap
runIdentity . getCompose . traverse (Compose . Identity . f . g)
Compose。身份
是一种应用性转换,因此根据自然性
runIdentity . getCompose . Compose . Identity . traverse (f . g)
倒数崩溃
traverse (f . g) -- RHS
为完整起见,援引的法律和推论:
-- Composition:
traverse (Compose . fmap g . f) = Compose . fmap (traverse g) . traverse f
-- Naturality:
t . traverse f = traverse (t . f) -- for every applicative transformation t
-- `fmap` as traversal:
fmap g = runIdentity . traverse (Identity . g)
后一个事实来自恒等式定律,遍历恒等式=恒等式
,加上fmap
,根据lambdabot,它是一个自由定理(参数性)
为了响应自由遍历::(a->fb)->ta->F(tb)
,拉姆达博特产生了
$map_F g . h = k . f => $map_F ($map_T g) . traverse h = traverse k . $map_T f
设置g=id
,使h=k。f
。然后得出结论
traverse (k . f) = traverse k . fmap f
那太令人印象深刻了。你是怎么想出这个getCompose的。撰写
trick?我建议提交此证明,以包含在数据的文档中。Haskell函子
s之间的自然转换可遍历
@dfeur保留函数为fmap
ped,以便t。fmap f=fmap f。t
表示任何f
(顺便提一下,这也源自应用程序转换的两个属性)。如果t
可以更改Functor
中的值,则无法保持。(当我试图探索我所写的自然转换时。你可能会发现它们或其中的链接很有用,尽管那里没有关于Applicative
的任何具体内容。)@dfeuer从这个意义上讲,非自然的应用转换不是应用转换,从定义上来说都是如此(虽然现在我想不起支持这一主张的参考文献)并且因为,对于一个应用转换t
,t(xy)=txty
,t(pure fy)=t(pure fy)=t(pure fy)=pure fy
t(fmap fy)=fmap fy
(即自然性)@dfeur顺便说一句,谢谢你通过编辑解压证明:)F
和T
对@free意味着什么?没什么,它们是任意类型的构造函数(可能它们需要是$map\u F
的函子才能有意义,但是travel
类型中的F
和t
无论如何都是函子)。是的。travel
仅假设在a
和b
中具有参数多态性。(事实上,它在f
中也有一定程度的多态性,尽管兰博特不知道如何考虑这一点(我也不知道)这真是太好了,因为这意味着我想要的定律根本不依赖于任何可遍历的
定律,甚至适用于特定于函子的遍历-类函数。不幸的是,这些自由定理背后的数学机制非常强大。回顾这个答案,值得注意的是,这是一个非常复杂的问题自由定理似乎是一个非常重要的定理。如果我们在上面做k=id
,我们就得到trasequencea=traseid.fmap f
。如果我们定义sequenceA=traseid
,这意味着trasea
可以分解成fmap
,而sequenceA
独立于trasequencea
ble法律。