gpt4 book ai didi

haskell - 如何删除这种类型的相互递归?

转载 作者:行者123 更新时间:2023-12-04 15:38:51 26 4
gpt4 key购买 nike

我遇到了一个相互递归的问题。我采用的基本结构是我有一个定义类型类的模块和几个定义该类型类实例的模块。然而,每个实例都是根据所有其他实例定义的。

如果该描述有点过于抽象,这里有一些代码,其结构类似于我的代码。 (我已经把它剪掉了很多,以使必要的部分变得明显,并在与整体结构无关的部分添加了一些省略号)。

我的类(class)如下所示:

data Result = ...

class Foo a where
openFoo :: Result -> IO (a, Result)
runFoo :: (a, Result) -> IO (a, Result)
closeFoo :: (a, Result) -> IO Result

然后我有实例
data XData = ...

instance Foo XData where
openFoo result = ...
runFoo (data, result) = do
currentEvent <- getEvent
case currentEvent of
EventA -> return (data, result)
EventB ->
(openFoo result :: IO YData)
>>= runFoo
>>= closeFoo
>>= curry return data
closeFoo (data, result) = ...
data YData = ...

instance Foo YData where
openFoo result = ...
runFoo (data, result) = do
currentEvent <- getEvent
case currentEvent of
EventA -> return (data, result)
EventB ->
(openFoo result :: IO XData)
>>= runFoo
>>= closeFoo
>>= curry return data
closeFoo (data, result) = ...

现在我可以通过将所有实例放入单个模块来简单地解决这个问题,但是我有 8 个实例,而不是我的示例中显示的 2 个实例,它们都是相互递归的。最重要的是,每个实例都非常大。这意味着生成的模块将是一个巨大的无法导航的困惑。

现在 haskell wiki has two suggestion用于解决相互递归问题,但它们实际上更多的是关于相互递归类型,它们都不会在这里工作。

无论如何,如果不简单地组合我的所有模块,是否可以绕过这种相互递归?

最佳答案

这是一种稍微笨拙的方法。首先,将递归定义放在一个模块中:

module Internal.Recursive

data XData = ...
data YData = ...

-- Recursive definitions...

然后从单独的模块重新导出每个定义:
module XData (IR.XData) where

import qualified Internal.Recursive as IR
module YData (IR.XYata) where

import qualified Internal.Recursive as IR

这将给出相互递归模块的外观。 (我不相信 GHC 允许任何简单的方法来制作实际的递归模块。)

关于haskell - 如何删除这种类型的相互递归?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55070688/

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