问题标签 [phantom-types]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
haskell - 消除列表中的幻像类型
我在弄清楚如何在列表中的 ST monad 中运行计算时遇到了一些麻烦。
但是尝试编译它会出现以下错误:
如果我在 IO monad 中运行它,这将是一个简单的替换pure . map runST
为traverse runIO
(或其他)的问题,但我还没有弄清楚如何绕过幻像类型参数的存在。我怀疑该列表sts
需要为不同的列表元素具有不同的类型参数,因此需要是具有某种说服力的异构列表,但是包装 ST 单子只会引入旧错误之外的新错误。
处理此问题的最佳方法是什么,其中幻像类型变量被函数消除runST
,因此应该是统一的,但我无法说服类型检查器?
注意:我试图弄清楚的实际示例涉及inline-r
包中的 R monad,它也有一个幻像类型,并用 function 消除runRegion :: NFData a => (forall s. R s a) -> IO a
。我相信 ST monad 中的这个例子也应该抓住这里的根本问题,并且更广为人知。
haskell - 使用 QuickCheck 将 ST 与多态测试“模板”一起使用
我有一个具有关联单子的类,以便可以为不同的单子创建实例。
我想用QuickCheck
.
我想创建代表“法律”的函数,如下所示:
TestHarness
是辅助函数的元组:
为测试提供要使用的“Ref”,并将动作Property
分别转换为 a。
然后,我将能够使用“法律”和线束来实例化 QuickCheck 测试属性。
对于IO
,这没有问题:
编译并运行。
但是,我也有一个ST
例子:
然而,试图天真地定义一个测试工具,
失败并显示错误消息:
我猜我需要在某个地方进行量化,但我还没有通过反复试验成功地确定哪里。
是否可以ST
像这样参数化我的线束类型?
我该如何去做我想做的事?
haskell - 了解ST的量化和幻型
我正在尝试使用Test.QuickCheck.Monadic
.
该模块提供了一个线束
执行ST
-based 测试和一个函数
将任何动作提升到测试单子中。
在我的代码中,我有一个多态单子动作:
以下函数
编译失败:
但是这个
编译没有问题。
谁能解释一下?
haskell - Haskell 的“Const”函子是否类似于范畴论中的常数函子?
我知道 Haskell 中的许多名称都受到范畴论术语的启发,我试图准确理解类比的开始和结束位置。
类别Hask
由于一些关于严格/懒惰和的技术细节,我已经知道这Hask
不是(必然)一个类别seq
,但现在让我们把它放在一边。为了清楚起见,
- 的对象
Hask
是具体的类型,即 kind 的类型*
。这包括函数类型Int -> [Char]
,但不包括任何需要类型参数的东西,如Maybe :: * -> *
. 但是,具体类型Maybe Int :: *
属于Hask
。类型构造函数/多态函数更像是自然转换(或其他更一般的从Hask
自身到自身的映射),而不是态射。 - 的态射
Hask
是 Haskell 函数。对于两个具体类型A
和B
,hom 集Hom(A,B)
是具有签名的函数集A -> B
。 - 函数组合由 给出
f . g
。如果我们担心严格性,我们可能会将组合重新定义为严格,或者在定义函数的等价类时要小心。
Functor
s 是内函子Hask
我认为上面的技术细节与我在下面的困惑没有任何关系。我想我理解它的意思是说每个实例Functor
都是 category 中的一个 endofunctorHask
。也就是说,如果我们有
该Functor
实例以下列方式Maybe
对应于一个仿函数 from Hask
to :Hask
对于 中的每个具体类型
a
,Hask
我们分配具体类型Maybe a
对于 中的每个态射
f :: A -> B
,Hask
我们分配Maybe A -> Maybe B
发送Nothing ↦ Nothing
和的态射Just x ↦ Just (f x)
。
常数(endo)函子
类别 C 上的常量(endo)函子是一个函子,将类别 C 的Δc : C → C
每个对象映射到固定对象c∈C
,并将 C 的每个态射映射到固定对象的恒等态射id_c : c → c
。
这Const
Functor
考虑Data.Functor.Const
。为了清楚起见,我将在这里重新定义它,区分类型构造函数Konst :: * -> * -> *
和数据构造函数Const :: forall a,b. a -> Konst a b
。
这种类型检查是因为数据构造函数Const
是多态的:
我可以买那Konst m
是该类别中的一个内函子Hask
,因为在 implmenetation 中fmap
,
- 在左侧,
Const v
表现为 aKonst m a
,由于多态性,这是可以的 - 在右侧,
Const v
显示为 aKonst m b
,由于多态性,这是可以的
但是,如果我们试图将其Konst m :: * -> *
视为范畴论意义上的常数函子,我的理解就会崩溃。
什么是固定对象?类型构造函数
Konst m
接受一些具体类型a
并给我们一个Konst m a
,至少从表面上看,它是每个 不同的具体类型a
。我们真的想将每种类型映射a
到固定类型m
。根据类型签名,
fmap
接受一个f :: a -> b
并给我们一个Konst m a -> Konst m b
. 如果Konst m
类似于常量函子,则fmap
需要将每个态射发送到id :: m -> m
固定类型上的恒等态射m
。
问题
所以,这是我的问题:
Haskell 的
Const
函子在哪些方面类似于范畴论中的常数函子(如果有的话)?如果这两个概念不等价,甚至有可能
SimpleConst
在 Haskell 代码中表达范畴论常数函子(比如说)?我快速尝试了一下,并遇到了与上述幻象类型的多态性相同的问题:
如果#2 的答案是肯定的,如果是,那么在范畴论意义上,这两个 Haskell 函数有什么关系?也就是说,在 Haskell 中的
SimpleConst
to就像在范畴论中Const
的常量函子一样?__?__
Hask
幻像类型是否会像类别一样思考问题?我们是否需要修改 的定义,Hask
使对象真正成为类型的等价类,如果没有幻像类型参数,这些类型本来是相同的?
编辑:自然同构?
看起来多态函数是从函子到常量函子getConst :: forall a,b. Konst a b -> a
的自然同构的候选者,尽管我还不能确定后者是否可以在 Haskell 代码中表达。η : (Konst m) ⇒ Δm
Konst m
Δm : Hask → Hask
自然转化法则就是η_x = (Konst m f) . η_y
。我无法证明这一点,因为我不确定如何正式推理 a(Const v)
从 typeKonst m a
到的转换Konst m b
,除了挥手说“存在双射!”。
相关参考
以下是上面尚未链接的可能相关问题/参考的列表:
- StackOverflow,“Haskell 中的所有类型类都有类别理论类比吗?”
- StackOverflow,“Haskell 中的函子与范畴论中的函子有什么关系?”
- WikiBooks,Haskell/类别理论
rust - 使用特征作为幻像类型
在 Rust 中,我想使用幻像类型来正确键入一个简单的 id:
在第一个草稿版本中,我使用了具体的结构T
,一切都很好。然后在使用不同数据源的更精细的版本中,这些结构变成了特征。比方说:
但是使用traits作为幻像类型会带来问题:
- 编译器让我声明
T: ?Sized
,好像T
是可能需要的大小。我可以忍受,但由于目的PhantomData<T>
是告诉它T
不会被使用,我想知道是否还有其他方法? - 我收到警告:“不推荐使用没有明确 'dyn' 的特征对象”。我可以用 global 摆脱它
#![allow(bare_trait_objects)]
,但是这个警告在其他方面很有用,我不想这样做。有没有办法bare_trait_object
只允许“当用作”的类型参数时Id<T>
?
我当前的解决方案是在空结构和特征之间复制名称类型:
这很尴尬,但我找不到更好的。
scala - 未强制执行的方法的类型限制
我无法理解为什么编译器允许当前代码。
我使用幻像类型来保护对方法的访问。只有在特定的“状态”下才允许调用方法。
在大多数情况下,这个不变量确实是经过编译验证的。然而,有时编译器只是忽略了幻像类型所施加的约束。这感觉像是一个重大错误。我不明白什么?
我试图尽可能地简化问题。我的用例更复杂:
然后
正如您在上面看到的,客户端可以关闭一扇关闭的门。在我的库中,相应的行为是抛出运行时异常。(我确信异常得到了很好的保护并且无法访问)
我只能为返回布尔值的表达式复制此问题,并且当这是函数的参数时(在示例中,println
)
我不是在寻找替代解决方案,而是在寻找关于如何发生这种情况的解释?你不同意这是一个相当大的缺陷吗?或者,也许我错过了什么?
Scala version: 2.13.5
编辑
在讨论了gitter之后,我打开了错误请求@https ://github.com/scala/bug
问题似乎没有出现在 scala 3 中。
typescript - 打字稿可以在运行时检索幻像类型参数吗?
我正在使用一个非常复杂的 API,并且某些字段是限制性字符串(长度为 X 最大值的字符串)。所以我创建了这种类型:
它可以很好地创建具有我想要的格式的字符串,但是有交易,我必须用这种类型填充一个对象,但是每个键的最大长度可以不同,我需要知道要写的最大长度是多少在对象的关键。示例:
如果有人知道如何处理它,非常感谢!:)
haskell - `type` 与 phantom 的同义词不允许出现警告?
b
被称为“幻影类型”,因为它不会出现在=
. 这对于数据的类型级标记很有用。
(GHC 不抱怨,即使有:set -Wall
。)b
是什么?它有什么用处?
我觉得 GHC 应该警告我b
没有在 RHS 上使用。
typescript - 如何使幻像类型与 TypeScript 中的方法一起使用?
考虑以下使用幻像类型的程序:
上述程序类型检查是因为推断出正确的类型。该constant
值具有推断类型Const<boolean, never>
。该函数以、和map
类型调用。该函数以、和类型调用。A = boolean
B = string
C = number
contramap
A = boolean
B = number
C = string
但是,使用方法而不是函数来编写上述表达式会很好。因此,我尝试了以下方法:
如您所见,该map
方法有效,但该contramap
方法无效。这是因为 is 的类型constant
并且Const<boolean, never>
它没有被方法调用细化,即 formap
类型没有被细化到Const<boolean, string>
并且contramap
类型没有被细化到Const<boolean, number>
。
正因为如此,要么工作map
要么contramap
工作,但不能同时工作。如果对象的类型是Const<boolean, never>
则contramap
不起作用。如果对象的类型是Const<boolean, unknown>
则map
不起作用。
我怎样才能同时map
使用contramap
方法而不是函数来工作?
haskell - Convert Sum Type to Phantom Type via Type Classes
I was experimenting with phantom types in Haskell. My goal is to convert the LangCode
Type to it's corresponding Phantom Type representation via Type Classes for example DE
to Lang DE
.
With a type annotation it works fine. But without it I get this error.
My question is. Is it possible to implement it in a way so that the type annotations are no longer needed?
Updated version