gpt4 book ai didi

haskell - 是否可以从数据类型中普遍删除函数类型,以允许deriveJSON?

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

我有几种代表应用程序状态的数据类型。在数据类型的不同位置,我嵌入了函数或单子(monad)操作,例如。

data Foo = Foo Int (ActionM String)
data Bar = Bar Foo (Maybe Bar) (ActionM ())

我需要将大部分数据类型编码为 json,以便我可以将其发送到浏览器进行显示。使用deriveJSON(来自Aeson 包)不起作用,因为无法派生ActionM 的实例。然而,我实际上并不希望发送这些位。我目前有一种可行的方法,但基本上是复制粘贴全套数据类型并手动删除嵌入的 ActionM 字段。

我(认为我)需要以下几件事之一。要么

  • 一种告诉deriveJSON忽略它无法识别的字段的方法,并且可能将它们解析回未定义。据我所知这不存在
  • 一种自动生成一组并行数据类型并删除这些字段的方法。所以我想写一些类似的东西

applyMagic Bar

然后回来

data Foo' = Foo' Int
data Bar' = Bar' Foo' (Maybe Bar')

这一切可能吗?我该怎么做?

最佳答案

这是一个简单的解决方案,但你不能做类似的事情

data Foo' = Foo' Int

type Foo = (ActionM String, Foo')

当你想序列化时,只需获取元组的第二个元素?

元组是 ComonadEnv 的一个实例,因此您还可以使用 askextract 等函数。

编辑。 Bar 是一个更复杂的情况,因为它是递归类型。但它可以使用 CofreeT 来处理comonad 变压器:

import Data.Functor.Identity
import Data.Bifunctor (second)
import Control.Comonad -- from 'comonad'
import Control.Comonad.Hoist.Class
import Control.Comonad.Trans.Cofree -- from 'free'

-- Orphan ComonadHoist instance that will likely be added in future
-- versions of free
instance Functor f => ComonadHoist (CofreeT f) where
cohoist g = CofreeT . fmap (second (cohoist g)) . g . runCofreeT

type Bar = CofreeT Maybe ((,) (ActionM ())) Foo
type Bar' = Cofree Maybe Foo'

applyMagic :: Bar -> Bar'
applyMagic = cohoist (Identity . extract) . fmap extract

CofreeT Maybe ((,) (ActionM ())) Foo 是已使用 ActionM () 注释的 Foo 值的非空列表 值。

Cofree Maybe Foo'Foo' 值的非空列表,没有额外的注释(Cofree Maybe FooCofreeT Maybe Identity Foo',其中 Identity 作为简单的共同点。)。

要将一个转换为另一个,applyMagic 首先使用 fmap extract 将所有 Foo 转换为 Foo's,然后使用 cohoistComonadHoist 删除 CofreeT 下面的“注释层”。

一般来说,具有“额外上下文”的值通常可以使用 comonad 进行建模。

关于haskell - 是否可以从数据类型中普遍删除函数类型,以允许deriveJSON?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31365904/

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