gpt4 book ai didi

haskell - 使用类型在 Haskell 中建模序列值转换的好方法?

转载 作者:行者123 更新时间:2023-12-01 10:42:24 25 4
gpt4 key购买 nike

假设我有一个名为 Report 的假设类型,如下所示:

data Report = Report {
juniorReview :: Maybe (Person, Bool)
, seniorReview :: Maybe (Person, Bool)
... many other fields
}

和简化的功能,如:

addJuniorReview :: Report -> (Person, Bool) -> Report

addSeniorReview :: Report -> (Person, Bool) -> Report

报告 必须经过一个序列,在这个序列中,初级审阅者被附加并批准或不批准(元组中的 bool 值),然后高级审阅者执行相同的操作。它必须始终按此顺序执行序列。但是类型系统并不强制执行此操作。我愿意。最好的方法是什么?我也愿意重新设计数据类型。

还假设 Report 必须经过许多其他步骤才能达到其完成状态,每个步骤都会向其字段添加更多数据位。我想要一个易于扩展到包含许多步骤的多阶段流程的解决方案。

编辑

另一个要求是该值必须在每个中间状态下都可以显示。中间状态不能是不完整的构造函数,例如 (Person,Bool) -> Report

最佳答案

您当前的类型与您的域根本不匹配:它可以表示无效状态。特别是,我们可以有各种没有意义的 Nothing 组合:

Report Nothing Nothing
Report Nothing (Person, True)

这个问题的一个很好的解决方案是用一种类型(或者更可能是多种类型)替换报告的模型,以排除像这样的无效状态。

这个特殊情况非常简单,您的序列中有有限数量的不同事物。我只是将两者直接建模为两种不同的类型:

data Report = Report { ... many other fields ... }

data JuniorReport = JuniorReport (Person, Bool) Report

data SeniorReport = SeniorReport (Person, Bool) JuniorReport

那么你的函数看起来像这样:

addJuniorReport :: Report -> (Person, Bool) -> JuniorReport
addSeniorReport :: JuniorReport -> (Person, Bool) -> SeniorReport

如果您的整个过程不太复杂或不太动态,那么扩展这种方法以在您的类型中对其进行显式编码是合理的。

一种更灵活、更简洁但稍微更困难的方法是将流程的当前阶段编码为 Report 上的幻像类型。幻像类型是类型本身不使用的类型参数,可让您向类型添加任意附加约束。它可能看起来像这样:

data Report stage = Report { ... }

data JuniorReview
data SeniorReview
...

addJuniorReview :: Report () -> (Person, Bool) -> Report JuniorReview
addSeniorReview :: Report JuniorReview -> (Person, Bool) -> SeniorReview

底层报表数据结构在每一步都是相同的,您只是添加了一个类型注释,说明它在流程的哪一步。

如果您的步骤非常多,您可以使用类型级符号而不是空数据类型来进行注释。这将允许您在类型级别使用字符串文字来表示每个步骤:

{-# LANGUAGE DataKinds, KindSignatures #-}
import GHC.TypeLits

data Report (a :: Symbol) = Report {}

addJuniorReview :: Report "Start" -> Report "JuniorReview"

但是,它仍然为您提供了良好的错误预防和 self 记录水平。此外,您可以通过保持报告类型抽象并且不导出构造函数来避免大多数可能的问题,确保它只能使用模块中的函数创建。

关于haskell - 使用类型在 Haskell 中建模序列值转换的好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29152593/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com