我想映射到 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, va 分别是位置、速度和加速度的数组。
定义 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