康纳·麦克布赖德(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 无关
换位。
换句话说,
transpose
和transpose''
似乎无关功能-不同的例子。我想念什么吗?
最佳答案
其中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/