【问题标题】:Wiring/ArrowLooping every element in a list with every other element in the list将列表中的每个元素与列表中的所有其他元素连接/箭头循环
【发布时间】:2014-01-18 12:02:40
【问题描述】:

我之前问过一个关于这个的问题,但我认为我真的不知道我在问什么。我想我现在对我的问题有了更好的理解。

我正在使用 netwire,一个带箭头的 FRP 库,但在实现这个箭头循环时遇到了一些麻烦。

我有

f :: ArrowLoop r =>  a  -> r [a]  a
g :: ArrowLoop r => [a] -> r ()  [a]

这样g 基本上使用f 将给定列表中的每个元素与所有其他元素的列表联系起来......嗯......这很难用文字来表达,所以我将举一个例子长度为 4 的列表:

g [x0, x1, x2, x3] = proc _ -> do
  rec
     y0 <- f x0 -< [y1, y2, y3]
     y1 <- f x1 -< [y0, y2, y3]
     y2 <- f x2 -< [y0, y1, y3]
     y3 <- f x3 -< [y0, y1, y2]
  returnA -< [y0, y1, y2, y3]

(我有一个辅助函数selects :: [a] -&gt; [(a,[a])],它将[x,y,z] 之类的东西变成[(x, [y,z]), (y, [x,z]), (x, [x,y])])

现在...我已经编译了这个硬编码版本,它已经可以正常工作并提供我最想要的结果。它运行时没有任何时髦的问题。

有谁知道是否有可能做这个“精确”的事情......但是使用一般数量的列表元素?


作为参考,我对selects 的实现来自 Simon Marlow,

selects :: [a] -> [(a,[a])]
selects = go []
  where
    go xs [] = []
    go xs (y:ys) = (y,xs++ys) : go (y:xs) ys

【问题讨论】:

    标签: haskell arrows netwire


    【解决方案1】:

    我无法正确测试它,因为我没有任何示例 f 可以运行它,但我相信这概括了您拥有的箭头模式:

    g :: ArrowLoop r => [a] -> r () [a]
    g = listLoop . map f
    
    listLoop :: ArrowLoop r => [r [a] a] -> r () [a]
    listLoop l = const [] ^>> go l where
        go []     = arr (const [])
        go (r:rs) = proc bs -> do
            rec a  <- r     -< bs ++ as
                as <- go rs -< bs ++ [a]
            returnA -< a : as
    

    所以首先我们使用f 进行映射以获取箭头列表[f x0, f x1, ...],然后我们将其提供给我命名为listLoop 的组合器,该组合器接受一个箭头列表并定义一个递归箭头,它本质上具有相同的逻辑作为你的selects。 bs 是来自r 之前的箭头的结果列表(类似于selects 中的xs),as 是来自r 之后的箭头的结果。对于每个r,我们输入其他箭头的结果,而不是r 本身的结果(即a)。然后我们递归,将a 附加到前面的结果列表中。

    【讨论】:

    • 这个编译;很抱歉,我真的不能说什么,因为它最终由于某种原因起作用(我在计算中得到了很多 NaN)。如果你愿意,我可以得到一些简单的网线,也许你可以从那里去看看为什么它不起作用?不过,我感谢您的帮助。
    • 是的,如果您可以包含一些适用于您的硬编码 g 和一些简单、可运行的 main 的示例线路,我会很乐意进一步调试它。
    猜你喜欢
    • 1970-01-01
    • 2013-06-06
    • 2020-08-08
    • 1970-01-01
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    相关资源
    最近更新 更多