鉴于列表:: [(Foo, Bar)]
,我想在Bar
上执行scanl1,但保留其Foo
“代码”。
即。我想要一个类型为:: [(a, b)] -> ([b] -> [c]) -> [(a, c)]
的函数,这样我就可以传递一个curried scanl1
作为第二个参数。
我可以递归地编写它,但感觉有一种方法可以组成高阶函数来执行此操作。
这是否已经可以使用标准功能?
答案 0 :(得分:11)
您可以提升合并功能,使Foo
代码穿过,以便您仍然可以使用scanl1
,而不是写出令人不满意的高阶函数。
keeptags :: (Bar -> Bar -> Bar) -> (Foo,Bar) -> (Foo,Bar) -> (Foo,Bar)
keeptags g (_,b) (a',b') = (a',g b b')
现在你可以使用scanl1
;拿走原来的qux :: Bar -> Bar -> Bar
并制作
scanQux :: [(Foo,Bar)] -> [(Foo,Bar)]
scanQux = scanl1 (keeptags qux)
keeptags
很简单,scanQux
非常明确。
例如,如果
type Foo = Char
type Bar = Int
qux = (+)
然后你得到
*Main> scanl1 qux [1..9]
[1,3,6,10,15,21,28,36,45]
*Main> zip "HELLO MUM" [1..9]
[('H',1),('E',2),('L',3),('L',4),('O',5),(' ',6),('M',7),('U',8),('M',9)]
*Main> scanQux $ zip "HELLO MUM" [1..9]
[('H',1),('E',3),('L',6),('L',10),('O',15),(' ',21),('M',28),('U',36),('M',45)]
正如你所希望的那样。
答案 1 :(得分:4)
你的意思是,unzip
?
http://zvon.org/other/haskell/Outputprelude/unzip_f.html
x = zip a c
where
(a, b) = unzip my_list
c = what_ever_you_want_on b
答案 2 :(得分:2)
我的朋友带来了keeptags
的以下实现:
import Control.Arrow
keeptags g (_,b) = second (g b)
我认为它仍然可读。