哈斯克尔中的成对列表修改



我想编写一个modifyList函数,它接受数据结构的列表,使用函数modify修改它们并返回修改后的列表。 我遇到的问题是,我的modify函数从列表中获取元素对,并对两个元素进行更改。

这是我到目前为止的(简化(代码:

import qualified Data.Vector as V
import Data.List
data Structure = Structure{ factor :: Double
, position :: V.Vector Double
} deriving (Show)
-- Calculates a factor with values from both structures
calculateFactor :: (Structure, Structure) -> Double
calculateFactor (p, q) = (factor p) + (factor q) -- This calculation is simplified     
modify :: (Structure, Structure) -> (Structure, Structure)
modify (a, b) = ( a { position = V.map (+ structureFactor) (position a) }
, b { position = V.map (subtract structureFactor) (position b) })
where structureFactor = calculateFactor(a,b)
modifyList :: [Structure] -> [Structure]
modifyList l = [ ??? | (p, q) <- (map (modify) pairs)] -- What do I need to do here?
where pairs = [(x, y) | (x:ys) <- tails l, y <- ys]

如何进行这些修改,以便后续函数调用可以使用更新的值?

例如,我定义了一些这样的数据:

p = Structure 2 (V.replicate 3 1.0)
q = Structure 3 (V.replicate 3 1.0)
u = Structure 4 (V.replicate 3 1.0)
list = [p, q, u]

现在modifyList list应该为列表中的每个元素对调用modify(p, q) (p, u) (q, u)它给了我一个对的结果列表:

[(Structure {factor = 2.0, position = [6.0,6.0,6.0]}, -- Modified p
Structure {factor = 3.0, position = [-4.0,-4.0,-4.0]}), -- Modified q
(Structure {factor = 2.0, position = [7.0,7.0,7.0]}, -- Also modified p
Structure {factor = 4.0, position = [-5.0,-5.0,-5.0]}), -- Modified u
(Structure {factor = 3.0, position = [8.0,8.0,8.0]}, -- Also q
Structure {factor = 4.0, position = [-6.0,-6.0,-6.0]})] -- Also u

但我实际上想要得到的是与[p, q, u]相同的列表,其中pposition = [12.0, 12.0, 12.0]好像我手动调用了p' = fst(modify (p, q))然后调用p = fst(modify(p', u))为原始position p提供值。q分别应该有position = [3.0, 3.0, 3.0]uposition = [-12.0, -12.0, -12.0]

命令式语言的伪代码可能如下所示:

Structure = {Double factor, Vector position};
Structure[] list = {p, q, u};
for i = 0; i < list.length; i++;
for j = i+1; j < list.length; j++;
structureFactor = calculateFactor(list[i], list[j]);
//Destructive updates
list[i].position += structureFactor; //Add factor to each vector value
list[j].position -= structureFactor;

我尝试过使用可变向量,但尝试将这些包含在我的数据结构中失败了,因为我对 Haskell 的理解太基本了,我什至不确定这种方法是否有意义。

有什么简单的方法可以做到这一点吗?

好的,我认为这就是你想要做的:有一个函数,对于列表中的每对元素(与列表中的顺序相同(,计算该对上的一些修改函数,然后将结果放回它们的来源。

mapPairs :: ((a,a)->(a,a)) -> [a] -> [a]
mapPairs f [] = []
mapPairs f (x:xs) = s : mapPairs f res where
rec a [] = (a,[])
rec a (y:ys) = let (b,c) = f (a,y)
(a',l') = rec b ys in
(a',c:l')
(s,res) = rec x xs

我认为这有效,但我手头没有电脑。但是,您似乎可能想要一个不同的解决方案。无论如何,这是如何写modifyList

modifyList = mapPairs modify

这是实际解决您的问题的尝试:

postFactors' [] = []
postFactors' (x:xs) = case postFactors' xs of
[] -> factor x : [0]
a:as -> (factor x + a) : a : as
postFactors = tail . postFactors'
preFactors = scanl (+) 0 . map factor
addPos v f = v {position = V.map (+f) $ position v}
modifyList l = zipWith (-) (postFactors l) (preFactors l) & zipWith addPos l

描述:从列表的每个元素之前/之后的所有内容中查找因素的总和。然后找到他们的不同之处。然后将其添加到每个元素的位置

相关内容

  • 没有找到相关文章

最新更新