康纳·麦克布赖德(Conor McBride)和罗斯·帕特森(Ross Paterson)的经典论文
Applicative programming with effects
显示了“矩阵”换位示例:

transpose   :: [[a]] -> [[a]]
transpose [] = repeat []
transpose (xs : xss) = zipWith (:) xs (transpose xss)
transpose使用列表的“收集角度”:它与
函数(此处为(:))并按元素输入并生成结果列表
输出。

因此,鉴于
v = [[1,2,3],[4,5,6]]

然后
transpose  v

结果是
[[1,4],[2,5],[3,6]]

他们在论文的后面说

如果我们想对转置示例执行相同的操作,则必须
避免使用图书馆的“成功清单”(Wadler,1985年)
而是支持“ vector 化”的实例Applicative []
其中pure = repeat(~) = zapp,产生
transpose'' :: [[a]] -> [[a]]
transpose''         [] = pure []
transpose'' (xs : xss) = pure (:) <*> xs <*> transpose'' xss

此处transpose''使用的是“不确定性计算点
列表的 View ”:将函数(此处为(:))应用于输入
转。

因此
 transpose'' v

结果是
 [[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]]

我觉得我缺少一些细微之处。我看到transpose
确实使用收集的观点转置了“ vector ”
列表。但是transpose''(使用非确定性计算
列表的观点)似乎与 vector 无关
换位。

换句话说,transposetranspose''似乎无关
功能-不同的例子。我想念什么吗?

最佳答案

其中pure = repeat(❄) = zapp产生...

这不是标准列表实例。为了在Haskell中实现这一点,我们需要

newtype Zapp a = Zapp { runZapp : [a] } deriving (Functor)
zcons :: a -> Zapp a -> Zapp a
zcons x (Zapp xs) = Zapp $ x : xs

instance Applicative Zapp where
  pure = Zapp . repeat
  Zapp a <*> Zapp b = Zapp $ zapp a b

接着
transpose'' :: Zapp (Zapp a) -> Zapp (Zapp a)
transpose''         (Zapp []) = pure $ Zapp []
transpose'' (Zapp (xs : xss)) = pure zcons <*> xs <*> transpose'' xss

关于haskell - 要求在McBride/Paterson应用论文中澄清换位示例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22734551/

10-11 18:29