gpt4 book ai didi

generics - 使用 GHC.Generics 或 Data.Data 类型族

转载 作者:行者123 更新时间:2023-12-03 22:08:23 30 4
gpt4 key购买 nike

这是一个与我的模块有关的问题 here , 并且被简化了一点。也与 this 有关上一个问题,我在其中过度简化了我的问题并且没有得到我正在寻找的答案。我希望这不是太具体,如果您能想到更好的标题,请更改标题。

背景

我的模块使用并发 channel ,分为读取端和写入端。我使用具有关联类型同义词的特殊类来支持多态 channel “加入”:

{-# LANGUAGE TypeFamilies #-}

class Sources s where
type Joined s
newJoinedChan :: IO (s, Messages (Joined s)) -- NOT EXPORTED

--output and input sides of channel:
data Messages a -- NOT EXPORTED
data Mailbox a

instance Sources (Mailbox a) where
type Joined (Mailbox a) = a
newJoinedChan = undefined

instance (Sources a, Sources b)=> Sources (a,b) where
type Joined (a,b) = (Joined a, Joined b)
newJoinedChan = undefined

-- and so on for tuples of 3,4,5...

上面的代码允许我们做这样的事情:
example = do
(mb , msgsA) <- newJoinedChan
((mb1, mb2), msgsB) <- newJoinedChan
--say that: msgsA, msgsB :: Messages (Int,Int)
--and: mb :: Mailbox (Int,Int)
-- mb1,mb2 :: Mailbox Int

我们有一个称为 Behavior 的递归操作。我们可以在从 channel “读取”端拉出的消息上运行:
newtype Behavior a = Behavior (a -> IO (Behavior a))
runBehaviorOn :: Behavior a -> Messages a -> IO () -- NOT EXPORTED

这将允许我们运行 Behavior (Int,Int)msgsA 中的任何一个上或 msgsB ,在第二种情况下, Int它收到的元组中的 s 实际上来自单独的 Mailbox es。

对于暴露的 spawn 中的用户,这一切都捆绑在一起。功能
spawn :: (Sources s) => Behavior (Joined s) -> IO s

...调用 newJoinedChanrunBehaviorOn , 并返回输入 Sources .

我想做的事

我希望用户能够创建 Behavior任意产品类型(不仅仅是元组),例如我们可以运行 Behavior (Pair Int Int)关于示例 Messages以上。我想用 GHC.Generics 来做这件事同时仍然具有多态 Sources ,但无法使其工作。
spawn :: (Sources s, Generic (Joined s), Rep (Joined s) ~ ??) => Behavior (Joined s) -> IO s

上述示例中实际暴露在 API 中的部分是 fstnewJoinedChan行动,和 Behavior s,因此可接受的解决方案可以修改 runBehaviorOn 中的一个或全部或 sndnewJoinedChan .

我还将扩展上面的 API 以支持总和(尚未实现),如 Behavior (Either a b)所以我希望 GHC.Generics 对我有用。

问题
  • 有没有办法可以扩展上面的 API 以支持任意 Generic a=> Behavior a ?
  • 如果不使用 GHC 的泛型,是否有其他方法可以让最终用户痛苦最小地获得我想要的 API(即他们只需要在他们的类型中添加一个派生子句)?例如与 Data.Data ?
  • 最佳答案

    也许是这样的?

    {-# LANGUAGE TypeFamilies, DeriveGeneric, DefaultSignatures, TypeOperators, FlexibleInstances, FlexibleContexts, UndecidableInstances #-}

    import Control.Arrow
    import GHC.Generics

    class Sources s where
    type Joined s
    newJoinedChan :: IO (s, Messages (Joined s)) -- NOT EXPORTED
    default newJoinedChan :: (Generic s, SourcesG (Rep s)) => IO (s, Messages (JoinedG (Rep s)))
    newJoinedChan = fmap (first to) newJoinedChanG

    class SourcesG g where
    type JoinedG g
    newJoinedChanG :: IO (g a, Messages (JoinedG g))

    --output and input sides of channel:
    data Messages a -- NOT EXPORTED
    data Mailbox a

    instance Sources (Mailbox a) where
    type Joined (Mailbox a) = a
    newJoinedChan = undefined

    instance (Sources a, Sources b)=> Sources (a,b) where
    type Joined (a,b) = (Joined a, Joined b)
    newJoinedChan = undefined

    instance (SourcesG a, SourcesG b) => SourcesG (a :*: b) where
    type JoinedG (a :*: b) = (JoinedG a, JoinedG b)
    newJoinedChanG = undefined

    instance (SourcesG a, Datatype c) => SourcesG (M1 D c a) where
    type JoinedG (M1 D c a) = JoinedG a
    newJoinedChanG = fmap (first M1) newJoinedChanG

    instance (SourcesG a, Constructor c) => SourcesG (M1 C c a) where
    type JoinedG (M1 C c a) = JoinedG a
    newJoinedChanG = fmap (first M1) newJoinedChanG

    instance (SourcesG a, Selector c) => SourcesG (M1 S c a) where
    type JoinedG (M1 S c a) = JoinedG a
    newJoinedChanG = fmap (first M1) newJoinedChanG

    instance Sources s => SourcesG (K1 i s) where
    type JoinedG (K1 i s) = Joined s
    newJoinedChanG = fmap (first K1) newJoinedChan

    newtype Behavior a = Behavior (a -> IO (Behavior a))

    runBehaviorOn :: Behavior a -> Messages a -> IO ()
    runBehaviorOn = undefined

    spawn :: (Sources s) => Behavior (Joined s) -> IO s
    spawn = undefined

    data Pair a b = Pair a b deriving (Generic)

    instance (Sources a, Sources b) => Sources (Pair a b) where
    type Joined (Pair a b) = JoinedG (Rep (Pair a b))

    关于generics - 使用 GHC.Generics 或 Data.Data 类型族,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13448361/

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