gpt4 book ai didi

haskell - 这个仿函数式标签的类型类的名称是什么?

转载 作者:行者123 更新时间:2023-12-02 02:47:40 26 4
gpt4 key购买 nike

我注意到我有很多函数可以为我的值添加某种标签。例如,考虑这两种数据类型:

data Named a = Named String a                                                   
data Colored a = White a | Black a

以及一些使用它们的函数:
name :: Foo -> Named Foo
color :: Named Foo -> Colored (Named Foo)

在某些时候,我开始拥有带有许多类似嵌套“标签”的函数,所以我想知道是否可以将其概括为更易于管理。所有这些都可能很好地与 PureScript 的行多态性配合使用,但我们在这里谈论的是 Haskell。无论如何,这就是我想出的:
class Tag f where                                                  
separate :: f a -> (forall b. b -> f b, a)

法律应该是这样的:
fx = let (f, x) = separate fx in f x

或者不进行类型检查但更优雅的版本:
uncurry ($) . separate = id
Tag也可以成为 Functor 的子类前提是
fmap g fx = let (f, x) = separate fx in f (g x)

例如数据类型的实例如下:
instance Tag Named where
separate (Named name x) = (Named name, x)

instance Tag Colored where
separate (White x) = (White, x)
separate (Black x) = (Black, x)

...以及其他一些一般情况:
instance Tag Identity where
separate (Identity x) = (Identity, x)

instance (Tag f, Tag g) => Tag (Compose f g) where
separate (Compose fgx) =
let (f, gx) = separate fgx in
let (g, x) = separate gx in
(Compose . f . g, x)

使整个类型类真正有用的是这个函数:
reorder :: (Tag f, Tag g) => f (g a) -> g (f a)
reorder fgx =
let (f, gx) = separate fgx in
let (g, x) = separate gx in
g (f x)

它看起来像一些明显的习语,所以它必须已经为社区所知。当您不知道要搜索的事物的名称并且 Hoogle 没有任何结果时,Google 的帮助不是很大。

所以我在这里,寻找一个名字,甚至一些图书馆,看看我还能用那个东西做些什么。

最佳答案

user2407038's comment确实触及了它的核心,因为您最终要表达的概念归结为与某个对仿函数同构的仿函数——毕竟,对是一个附加了其他东西的值。从这个角度来看,有一些可能有趣的额外事情需要注意。

为方便起见,我将假设您的 Tag s 是 Functor s(您提到的相关条件通过参数化成立),并通过替换 forall b. b -> f b 来简化类型与同构f () .那么我们可能有:

separate :: Tag f => f a -> (f (), a)

随着法律:
slot . separate = id

其中左逆是:
slot :: Functor f => (f (), a) -> f a
slot (sh, a) = fmap (const a) sh

通过添加 slot 的要求应该是满射的(就您的用例而言,这是完全合理的), slot升级为完全逆,从而为我们提供了 f a 之间的同构和 (f (), a) .

这些功能至少存在于生态系统中的一处: the adjunctions package :
splitL :: Adjunction f u => f a -> (a, f ())
unsplitL :: Functor f => a -> f () -> f a

Hask/Hask 左伴随与成对仿函数同构,对于 Hask/Hask 右伴随如何是双重的 Representable ,即同构于函数仿函数。 dfeuer's suspicion是,在某种程度上,是合理的,虽然附加词没有给我们左伴随对应物 DistributiveRepresentable .这是他们的草图,并有名字:
class Traversable t => Lone t where
codistribute :: Functor f => t (f a) -> f (t a)
surround :: Functor f => (a -> f b) -> t a -> f (t b)

class Lone f => Detachable f where
type Corep f
cotabulate :: (Corep f, a) -> f a
coindex :: f a -> (Corep f, a)

关于 Traversable的几点说明联系:
  • codistributesurround只是 sequenceAtraverse ,分别,除了 Applicative约束放宽到 Functor (如果始终只有一个值,则不需要 Applicative)。
  • 同理,cotabulatecoindex (或 slotseparate ,或 unsplitLsplitL )可以看作是 the shape-and-contents decomposition of traversable functors 的表现形式(其中我们不需要内容的列表/向量,因为同样,总是只有一个值)。
  • 可以想象成对的各种实例可以通过 Detachable 进行翻译。 .对于 Comonad ,甚至不需要,因为 Lone就足够了(另见 extractL and duplicateL 来自附件)。
  • surround是一个 van Laarhoven 镜头(一个 Lens (t a) (t b) a b,用镜头的说法),就像 traverse是 van Laarhoven 遍历 ( Traversal (t a) (t b) a b )。

  • 最后但并非最不重要的是, codistribute是您的 reorder 的概括.

    关于haskell - 这个仿函数式标签的类型类的名称是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37039042/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com