如何在Haskell中安全地对种类受限的类型变量进行装箱? 问题:
我想对一个类型变量进行案例分析,由于种类限制,该类型变量的可能性有限。我想静态地知道,套管总是会发现这些有限的可能性之一。我想不出如果没有一个无法达到的通病,如何写这个案例 作为一个具体的例子,假设我有一个数据类型如何在Haskell中安全地对种类受限的类型变量进行装箱? 问题:,haskell,types,Haskell,Types,我想对一个类型变量进行案例分析,由于种类限制,该类型变量的可能性有限。我想静态地知道,套管总是会发现这些有限的可能性之一。我想不出如果没有一个无法达到的通病,如何写这个案例 作为一个具体的例子,假设我有一个数据类型 data{-kind-} Temp = Hot | Cold 然后,我的目标是编写一个函数,如下面的castemp,它确定给定的Temp类型。差不多 data CaseTemp (t :: Temp) where IsHot :: CaseTemp 'Hot IsCold
data{-kind-} Temp = Hot | Cold
然后,我的目标是编写一个函数,如下面的castemp
,它确定给定的Temp
类型。差不多
data CaseTemp (t :: Temp) where
IsHot :: CaseTemp 'Hot
IsCold :: CaseTemp 'Cold
caseTemp :: forall (t :: Temp). CaseTemp t
caseTemp = ???
我可以对caseTemp
进行一些额外的限制,比如下面失败的尝试中的Typeable t
。甚至是用一种完全不同的方法
解决方案尝试失败
这是我最好的尝试,但它包含了一个我认为无法访问的分支,如果我在Temp
中添加另一个构造函数(在GHC 8.0.2中测试),它将允许caseTemp
以静默方式中断:
此尝试的问题是GHC认为Nothing->error“Unreachable!”
分支是可访问的
更新
User@Alec提到Any::Temp
是我不可能做我想做的事情的一个根本原因,因为
import GHC.Prim ( Any )
[...]
badCase :: CaseTemp Any
badCase = undefined :: CaseTemp Any
已被GHC接受。然而,
Any
是不可Typeable
的,所以我不清楚对caseTemp
施加约束不能解决这个问题。没有直接的方法,因为当eqT
返回Nothing
时,它没有质量证明
使用类型类怎么样
class IsTemp (b :: Temp) where
caseTemp :: CaseTemp b
没有直接的方法,因为当
eqT
返回Nothing
时,它没有质量证明
使用类型类怎么样
class IsTemp (b :: Temp) where
caseTemp :: CaseTemp b
这是因为
Any::Temp
@Alec,谢谢,我不知道Any
。我用一个例子更新了这个问题,说明了我认为你的意思。你对约束的评论很贴切。我鼓励您查看单身人士。它还使用约束来回避这类问题。此外,这正是下面给您的答案。:)这是因为Any::Temp
@Alec,谢谢,我不知道Any
。我用一个例子更新了这个问题,说明了我认为你的意思。你对约束的评论很贴切。我鼓励您查看单身人士。它还使用约束来回避这类问题。此外,这正是下面给您的答案。:)我更新了问题,明确表示我不在乎解决方案是如何实现的。我的代码只是一个不起作用的例子;不需要使用eqT
。那么,你是在建议我对所有我想装箱的t::Temp
设置一个IsTemp t
约束?这可能是可行的……事实上,类型类是使值依赖于类型的标准方法。我更新了问题,以明确我不关心解决方案是如何实现的。我的代码只是一个不起作用的例子;不需要使用eqT
。那么,你是在建议我对所有我想装箱的t::Temp
设置一个IsTemp t
约束?这可能是可行的……事实上,类型类是使值依赖于类型的标准方法。