【发布时间】:2011-05-17 13:51:35
【问题描述】:
我想在 Applicative 表单上映射。
类地图函数的类型如下:
mapX :: (Applicative f) => (f a -> f b) -> f [a] -> f [b]
用作:
result :: (Applicative f) => f [b]
result = mapX f xs
where f :: f a -> f b
f = ...
xs :: f[a]
xs = ...
作为这篇文章的背景,我尝试参考 Paul Haduk 的“The Haskell School of Expression”用 Applicative 风格编写流体模拟程序,我想用 Applicative 风格表达模拟如下:
x, v, a :: Sim VArray
x = x0 +: integral (v * dt)
v = v0 +: integral (a * dt)
a = (...calculate acceleration with x v...)
instance Applicative Sim where
...
其中 Sim 类型表示模拟计算的过程,VArray 表示向量数组 (x,y,z)。 X, v a 分别是位置、速度和加速度的数组。
在定义 a 时会出现在 Applicative 形式上的映射。
我找到了我的问题的一个答案。
毕竟,我的问题是“如何提升高阶函数(如 map :: (a -> b) -> [a] -> [b]) 到 Applicative 世界?”和答案 我发现是“使用提升的一阶函数构建它们。”
例如,“mapX”是用提升的一阶函数定义的 (headA, tailA, consA, nullA, condA) 如下:
mapX :: (f a -> f b) -> f [a] -> f [b]
mapX f xs0 = condA (nullA xs0) (pure []) (consA (f x) (mapA f xs))
where
x = headA xs0
xs = tailA xs0
headA = liftA head
tailA = liftA tail
consA = liftA2 (:)
nullA = liftA null
condA b t e = liftA3 aux b t e
where aux b t e = if b then t else e
【问题讨论】:
-
您的第一个代码块中不应该有
f :: f a -> f b(不是f :: (f a -> f b) -> f [a] -> f [b])吗?还是我误会了什么? -
谢谢!我错了 f 的类型。
-
顺便问一下,你能勾勒出你想象的
a的样子吗?我认为您可以通过不需要mapX的方式来做到这一点。 -
a 的草图如下(不准确): a = liftA sum $ mapX aux $ liftA2 neighbors (x!i) nbr where aux :: f Int -> f Vector3 aux i = 。 ..“liftA2 邻居 (x!i) nbr”的类型是“f [Int]”
-
您可以通过编辑将代码添加到您的帖子中吗?并在您使用时填写辅助功能?谢谢。
标签: haskell applicative