gpt4 book ai didi

haskell - 如何以类似于其他语言中的 mixins/方法修饰符/特征的方式促进代码重用?

转载 作者:行者123 更新时间:2023-12-04 04:13:16 24 4
gpt4 key购买 nike

我正在研究一些与建模持久图的数据库模式接口(interface)的代码。在详细讨论我的具体问题之前,我认为这可能有助于提供一些动力。我的架构围绕书籍、人物和作者角色。一本书有许多作者角色,每个角色都有一个人。但是,您必须创建一本新书,并对新版本进行修改,而不是允许对书籍对象进行直接 UPDATE 查询。

现在,回到 Haskell 领域。我目前正在使用一些类型类,但重要的是我有 HasRolesEntity :

class HasRoles a where
-- Get all roles for a specific 'a'
getRoles :: a -> IO [Role]

class Entity a where
-- Update an entity with a new entity. Return the new entity.
update :: a -> a -> IO a

我的问题来了。当您更新一本书时,您需要创建一个新的图书版本,但您还需要复制以前的图书角色(否则您会丢失数据)。最简单的方法是:
instance Entity Book where
update orig newV = insertVersion V >>= copyBookRoles orig

这很好,但是有一些东西让我感到烦恼,那就是缺乏对不变量的任何保证,如果某物是 EntityHasRoles ,然后插入新版本将复制现有角色。我想到了2个选项:

使用更多类型

一种“解决方案”是引入 RequiresMoreWork a b .从上面开始, insertVersion现在返回 HasRoles w => RequiresMoreWork w Book . update想要一个 Book , 所以要离开 RequiresMoreWork值,我们可以调用 workComplete :: RequiresMoreWork () Book -> Book .

真正的问题是,最重要的部分是 insertVersion 的类型签名。 .如果这与不变量不匹配(例如,它没有提到需要 HasRoles ),那么一切都会再次崩溃,我们又回到了违反不变量的问题上。

用 QuickCheck 证明它

将问题移出编译时间,但至少我们仍在断言不变量。在这种情况下,不变量类似于:对于同时也是 HasRoles 实例的所有实体,插入现有值的新版本应该具有相同的角色。

我对此有点困惑。在 Lisp 中我会使用方法修饰符,在 Perl 中我会使用角色,但在 Haskell 中有什么可以使用的吗?

最佳答案

处理具体情况,我会将角色作为类型而不是类的一部分

data Rolled a = Rolled a [角色]

instance Entity a => Entity (Rolled a)
其中 update (Rolled a rs) = Rolled (更新 a) rs

更一般地说,您可以只制作 Entity 的对实例

我还没有达到haskell zen,但我猜你最终应该在Writer或State monad(或他们的transformer版本)中工作

关于haskell - 如何以类似于其他语言中的 mixins/方法修饰符/特征的方式促进代码重用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7235630/

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