【发布时间】:2014-08-05 14:06:43
【问题描述】:
我已经搜索并搜索了以下内容,特别是堆栈溢出和一般的 Google。如果它已经被覆盖或微不足道以至于在任何地方都没有提及,我深表歉意。
我为有时是离散的,有时是连续的对象定义了一个自定义数据类型,如下所示:
data Gene = Discrete String Int | Continuous String Double
deriving (Eq, Show, Read, Ord)
这里,String 代表基因的名称(例如 vWF 或类似的),数字参数是它的状态,离散或连续,如下所示:
bober = Discrete "vWF" 2
slick = Continuous "gurg" 0.45432
我可以使用记录语法来访问基因的属性,但是对于名称和状态有 2 个不同的函数。我想要的是一种访问身份的功能,以及一种访问状态的功能。对于身份,这很简单,因为它是两个值构造函数的字符串:
geneName :: Gene -> String
geneName (Discrete dName _) = dName
geneName (Continuous cName _) = cName
当我尝试创建一个返回基因状态的函数时,我遇到了麻烦。我认为模式匹配会起作用:
geneState :: Num a => Gene -> a
geneState (Discrete _ dState) = dState
geneState (Continuous _ cState) = cState
这在 GHCi 中加载失败,给出:
DynamicalModularity.hs:34:35: 无法匹配类型
Int' withDouble' 预期类型:a 实际类型:双人 在表达式中:cState 在“geneState”的方程中: 基因状态(连续_cState)= cState 失败,已加载模块:无。
我尝试使用case 语法:
geneState :: Num a => Gene -> a
geneState gene = case gene of (Discrete _ dState) -> dState
(Continuous _ cState) -> cState
这再次无法加载:
DynamicalModularity.hs:30:56: 无法匹配类型
Int' withDouble' 预期类型:a 实际类型:双人 在表达式中:cState 在另一种情况下:(Continuous _ cState)-> cState 在表达式中: {的案例基因 (离散_dState)-> dState (连续_cState)-> cState } 失败,已加载模块:无。
我的问题是:我想做的事情是否可能和/或好的 Haskell?我错过了一些明显的东西吗?我一直在寻找解决方案一段时间。任何帮助将不胜感激。
【问题讨论】:
-
您对使用
geneState有何预期? -
GHC Haskell(existentials)中有这样的东西,但我想在推荐它们之前更好地理解这个问题。
-
返回一个存在量化的
Num实例是非常没用的。您可以.. 致电negate、abs和signum。那里没有任何有价值的东西。 -
@bheklilr
Either Int Double和Gene之间几乎没有区别(只是一个字符串),所以......为什么不直接返回您的输入? :P -
如果你认为 Bifunctors 是初学者的答案,我会更积极地提出存在主义 :-)