经过稍加搜索,我找到了一个StackOverflow的答案,它用comonoids必须满足的定律更好地解释了这一点。所以我想我明白了为什么在Haskell中只有一个假设的Comonoid类型的可能实例。
因此,要找到一个非平凡的comonoide,我想我们必须从其他类别中寻找。当然,如果范畴理论家有一个comonoids的名字,那么有一些有趣的。该页上的其他答案似乎暗示了一个涉及supply
的示例,但我找不出一个仍然满足这些规律的答案。
我还转到Wikipedia:有一个关于monoid的页面没有引用类别理论,在我看来,这是对Haskell的monoid
typeclass的充分描述,但“comonoid”重定向到对monoid和comonoid的类别理论描述,我无法理解,而且似乎仍然没有任何有趣的例子。
编辑:我不确定这是否真的是类别理论上的正确,但我在问题2的括号中想象的是delete::a->m()
和split::a->m(a,a)
对于一些特定的Haskell类型a
和Haskell单元体m
的非平凡定义,它们满足链接答案中comonoid定律的Kleisli-arrow版本。comonoids的其他例子仍然是受欢迎的。
正如Phillip JF所提到的,在子结构逻辑中谈论comonoid是很有趣的。我们来谈谈线性λ微积分。这很像您的普通类型的λ演算,除了每个变量必须使用一次。
为了获得一种感觉,让我们数一下给定类型的线性函数,即。
a -> a
只有一个居民,ID
。而
(a,a) -> (a,a)
(a, b) ↦ (a, a)
(a, b) ↦ (b, b)
(a, b) ↦ (a, b)
(a, b) ↦ (b, a)
data File
open :: String -> File
close :: File -> () -- consumes a file, but we're ignoring purity right now
t1 :: File -> File
t2 :: File -> File
close . t1 . t2 . open
close . t2 . t1 . open
close . t1 . open
close . t2 . open
let f1 = open "foo"
f2 = t1 f1
f3 = t2 f1
in close f3
因为我们使用了两次f1
。
现在,您可能想知道什么东西必须遵循线性规则。例如,我决定一些管道不必同时包含T1
和T2
(比较前面的枚举练习)。此外,我还介绍了open
和close
html" target="_blank">函数,它们愉快地创建和销毁file
类型,尽管这违反了线性。
实际上,我们可能会假设存在违反线性的函数--但并非所有客户机都可能。这很像io
单子--所有的秘密都存在于io
的实现中,因此用户可以在一个“纯粹”的世界中工作。
class Comonoid m where
destroy :: m -> ()
split :: m -> (m, m)
在线性lambda演算中实例化comonoid
的类型是一种具有携带破坏和复制规则的类型。换句话说,这是一种完全不受线性λ演算约束的类型。
由于Haskell根本没有实现线性lambda演算规则,所以我们总是可以实例化comonoid
instance Comonoid a where
destroy a = ()
split a = (a, a)
或者,从另一种角度来看,Haskell是一个线性LC系统,它只是碰巧为每个类型实例化comonoid
,并自动为您应用destroy
和split
。
[basic.def.odr]/3引用了术语“非平凡函数”,我在标准(N4140)中找不到它的定义。 [basic.def.odr]/3 除非将左值-右值转换(4.1)应用于x会产生一个不调用任何重要函数的常量表达式(5.19),并且如果x是一个对象,ex是表达式e的一组潜在结果的元素,其中左值-右值转换(4.1)应用于e,或者e是一个丢弃的值表达式(第5条)。
问题内容: 我需要使用这种结构将一些数据库表的内容转储到XML文件中 每个表在未知状态下的真实记录数,因此我无法将单个表的所有数据存储在内存中并转储到XML。 我的工作现在定义为: 这项工作不完整,无法满足我的需求,因为输出看起来像 我认为我必须丰富作家和/或编组人员的组件才能实现我的目标,但我还没有找到继续前进的好方法:( 我的问题是: 如何按照开始时所述构建复杂的XML结构,并使作业完全可重新
我正在尝试编写一个工厂函数来创建闭包,用作gstreamer中的“pad回调”。我已经提供了一个精简的例子,它应该可以在安装了gstreamer机箱和gstreamer二进制文件/插件的情况下编译。 通过我的研究,我使用了“impl-trait”方法,而不是装箱,使工厂函数工作。不过,我想找出装箱方法,因为它在某些情况下似乎更合适。 这是我得到的最接近。通过使用“Box”取消标记为<code>Cl
我希望有一个类型特征,对于任何在使用前不需要内存初始化的类型返回true,并且其复制构造函数可以作为memcpy实现。 我想让它回到真实 < li >整数类型(char、short int、int、long int等) < li >浮点数类型(float,double) < li>il::array (il::array是我自己对std::array的实现)for T是int、double、il:
当锁被释放后,任何一个线程都有机会竞争得到锁,这样做的目的是提高效率,但缺点是可能产生线程饥饿现象。
我知道POD类可以安全地设置。在c 17(?)std::is\U pod被std::is\U标准布局和std::is\U琐碎取代。如果一个非平凡但标准的布局结构只包含char[]数据和一个用户定义的构造函数,那么它可以安全地被memset吗。 具有数十个char[]成员变量的遗留类。 现有代码在使用对象时只对其执行memset。 我想在更新的结构B上调用用户定义的构造函数,因为除了“0”之外,还有