【问题标题】:Is the only `FlippyFloppyMorphism` `const mempty`?是唯一的`FlippyFloppyMorphism``const mempty`吗?
【发布时间】:2020-09-25 07:21:00
【问题描述】:

在 Haskell 中,我们有一个有趣的事实,即任何类型构造函数 f :: * -> * 同时是 FunctorContravariant 在其类型参数中都是幻像:

phantom :: (Functor f, Contravariant f) => f x -> f y

另一种说法是,同时为Functors 和Contravariant 的每个类型构造函数自然同构于Const x,对于某些x

这意味着实例化类的“唯一”方式(直到同构):

class FlippyFloppyFunctor f
  where
  ffmap :: Either (y -> x) (x -> y) -> f x -> f y

使其遵守函子定律:

ffmap (Left id)       = id
ffmap (Right id)      = id
ffmap (Left  (g . f)) = ffmap (Left f)  . ffmap (Left g)
ffmap (Right (f . g)) = ffmap (Right f) . ffmap (Right g)

是:

weirdmap :: Either (y -> x) (x -> y) -> Const r x -> Const r y
weirdmap = const $ \(Const x) -> Const x

即模新类型,const id.

我发现很难理解为什么这是其类型中唯一满足约束的函数,尽管我可以理解涉及absurd :: Void -> a/discard :: a -> () 的各种非正式论点,为什么存在这样的映射意味着仿函数在其类型参数中“是幻像”。

为了更好地理解它,我试图简化问题。与其考虑FlippyFloppyFunctor,不如想想:

class (Monoid a, Monoid b) => FlippyFloppyMorphism a b
  where
  ffmorph :: Either a a -> b

有类似的规律:

ffmorph (Left mempty)    = mempty
ffmorph (Right mempty)   = mempty
ffmorph (Left  (y <> x)) = ffmorph (Left x)  <> ffmorph (Left y)
ffmorph (Right (x <> y)) = ffmorph (Right x) <> ffmorph (Right y)

假设ab are non-commutative monoids,那么FlippyFloppyMorphism 的唯一合法实现仍然是const mempty?是否仍然可以解释为什么态射在输入幺半群中必须是“幻象”,而没有 Void() 可供参考?

【问题讨论】:

  • ExistsF 到底是什么?我似乎无法使用 Hoogle 找到它。
  • @bradrn 抱歉,这是早期草稿的产物,让我摆脱它。 (完成)
  • 我已经读了几遍了,但我不确定我是否理解FlippyFloppyMorphismFlippyFloppyFunctor 的关系...你能举一个FlippyFloppyMorphism 实例的例子吗?这可能会有所帮助。
  • @bradrn 这正是问题所在。我能想到的唯一合法的例子是ffmorph = const mempty。你能想到任何其他人,或者关于为什么不应该存在的论点吗?我想不出任何东西,但同时我无法就为什么不应该存在提出论据。
  • 啊,是的,我现在看到了这种关系……ffmorph 法律只是 ffmap 法律,(.)(&lt;&gt;) 取代。 (不知道为什么我以前没看到!)

标签: haskell monoids typeclass-laws


【解决方案1】:

在我看来,一般情况下的答案是“否”,因为幺半群可以是可交换的。

如果幺半群是可交换的,那么Dual aa 是同一个幺半群,而Either a aa 是同一个幺半群,因此我们只是退化为问ffmorph 是否是唯一的幺半群同态a -&gt; b。答案是“不”。

例如,对于加法的可交换幺半群,我们有replicate 'a' :: Either (Sum Int) (Sum Int) -&gt; String,其中:

replicateA (Left  0) = ""
replicateA (Right 0) = ""
replicateA (Left  (y + x)) = replicateA (Left x) ++ replicateA (Left y)
replicateA (Right (x + y)) = replicateA (Left x) ++ replicateA (Left y)

但是,我认为对于 _non_commutative monoids,唯一可能的实现可能是 const mempty(我仍然没有证据)。

【讨论】:

  • 我认为这个答案可能需要更正,因为编辑从问题中删除了Dual
  • @bradrn 我认为答案是正确的,我在编写它的过程中意识到我在问题中犯了错误。这个想法是我们要么需要翻转whatever (Left (y &lt;&gt; x)) 中的组合/附加顺序,要么我们需要翻转&lt;&gt; 本身,使用新类型。我在问题中做了both,这基本上导致Left 案例与Right 案例相同。
  • @bradrn 啊,没关系,你是对的。我在答案中确实有一个对Dual 的杂散引用。谢谢!
  • 是的,我说的是“杂散参考”。
猜你喜欢
  • 2012-05-29
  • 1970-01-01
  • 2011-12-26
  • 2016-08-22
  • 1970-01-01
  • 1970-01-01
  • 2019-05-29
  • 1970-01-01
相关资源
最近更新 更多