提升功能`a→b→c`到`[a]→[b]→[[c]]`

Man*_*erl 1 haskell nested-lists applicative traversable

我想有一个功能

foo :: (a ? b ? c) ? [a] ? [b] ? [[c]]
Run Code Online (Sandbox Code Playgroud)

采用一个函数f :: a ? b ? c和两个列表xsys并返回一个栅格(即,列表的列表)包含的值f应用于从值的每个组合xsys.

示例:foo [1..3] [4..6]应该返回

[[f 1 4,f 1 5,f 1 6],
 [f 2 4,f 2 5,f 2 6],
 [f 3 4,f 3 5,f 3 6]]
Run Code Online (Sandbox Code Playgroud)

我目前的做法是

foo = traverse . flip . traverse . flip
Run Code Online (Sandbox Code Playgroud)

这是有效的,但我想知道是否有其他方法或预先定义的组合器可以更好地完成(或者甚至可以合成,以便它可以很容易地扩展到三元或n元函数)

例如:如果我不想要一个结果网格而只需要一个结果列表,我可以编写f <$> xs <*> ys,这是简洁的,使用预定义的组合器,并以明显的方式推广到n-ary函数.是否有类似简洁的方法来编写我的组合器?

sve*_*son 7

这是列表推导的工作!

foo f xs ys = [ [ f x y | y <- ys ] | x <- xs]
Run Code Online (Sandbox Code Playgroud)

测试用例:

foo (\x y -> show x ++ " " ++ show y) [1..3] [4..6]
Run Code Online (Sandbox Code Playgroud)

收益率:

[["1 4","1 5","1 6"],["2 4","2 5","2 6"],["3 4","3 5","3 6"]
Run Code Online (Sandbox Code Playgroud)

  • 在这种情况下,IMO的完美可读性对于泛化/无点而言是一个巨大的优势 (3认同)