繁体   English   中英

访问自定义Haskell数据类型的函数

[英]Accessing functions for custom Haskell data types

我搜索并搜索了以下内容,特别是堆栈溢出和Google。 如果它已经被覆盖或者如此微不足道,以至于在任何地方都没有被提及,我会道歉。

我为有时离散且有时连续的对象定义了自定义数据类型,如下所示:

data Gene =  Discrete String Int | Continuous String Double 
                 deriving (Eq, Show, Read, Ord)

这里,String表示Gene的名称(例如vWF或其他),数值参数是其状态,离散或连续,如下所示:

bober = Discrete "vWF" 2
slick = Continuous "gurg" 0.45432

我可以使用记录语法来访问Gene的属性,但是有两个不同的名称和状态函数。 我想要的是一个访问身份的功能,一个访问状态的功能。 对于标识,这很简单,因为这是两个值构造函数的字符串:

geneName :: Gene -> String
geneName (Discrete dName _) = dName
geneName (Continuous cName _) = cName

当我尝试创建一个返回Gene状态的函数时,我遇到了麻烦。 我认为模式匹配会起作用:

geneState :: Num a => Gene -> a
geneState (Discrete _ dState) = dState
geneState (Continuous _ cState) = cState

这无法加载GHCi,给出:

DynamicalModularity.hs:34:35:无法匹配类型Int' with Double'预期类型:a实际类型:Double在表达式中:cState在`geneState'的等式中:geneState(Continuous _ cState)= cState Failed,modules已加载:无。

我尝试使用case语法:

geneState :: Num a => Gene -> a
geneState gene = case gene of (Discrete _ dState) -> dState
                              (Continuous _ cState) -> cState

再次这不加载:

DynamicalModularity.hs:30:56:无法匹配类型Int' with Double'预期类型:a实际类型:Double在表达式中:cState在备选案例中:(Continuous _ cState) - > cState在表达式中:case gene of {(Discrete _ dState) - > dState(Continuous _ cState) - > cState}失败,模块已加载:无。

我的问题是:我想做什么和/或好Haskell? 我错过了一些明显的东西吗 我一直在寻找解决方案。 任何帮助将不胜感激。

任何会消耗调用geneState结果的geneState都需要能够同时处理IntDouble geneState就是这种情况,因为我可以在离散值和连续值上调用geneState

让我们分别代表消耗IntDouble代码部分。 这两个部分都必须是简单的函数,所以我们可以把它们写成

intConsumer    :: Int    -> result
doubleConsumer :: Double -> result

现在我有这两个部分返回相同的结果,因为消费代码必须始终返回相同类型的事物,无论它是否接收离散或连续的Gene

现在,我们可以使用此信息和模式匹配编写geneState

geneState :: (Int -> result) -> (Double -> result) -> Gene -> result
geneState intConsumer doubleConsumer (Discrete   _ st) = intConsumer    st
geneState intConsumer doubleConsumer (Continuous _ st) = doubleConsumer st

我们可以简化此功能的一种方法是假设我们所有的消费者都单独使用Double s - 即使输入Gene是离散的。 这在数学上是合理的,因为Double包含所有的Int egers(如果你愿意,可以使它更正式)。

在Haskell中,函数fromIntegralInt转换为其他数字类型。 我们可以写

geneStateAsDouble :: Gene -> Double
geneStateAsDouble = geneState fromIntegral id

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM