6

给定一个 list :: [(Foo, Bar)],我想在Bars 上执行 scanl1,但保留它们的Foo“标签”。

即我想要一个带有 type 的函数:: [(a, b)] -> ([b] -> [c]) -> [(a, c)],这样我就可以传递一个 curriedscanl1作为第二个参数。

我可以递归地编写它,但感觉好像有一种方法可以组合高阶函数来做到这一点。

这是否已经可以通过标准功能实现?

4

3 回答 3

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)]

如你所愿。

于 2012-08-30T22:22:00.967 回答
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
于 2012-08-30T19:54:50.943 回答
2

我的朋友带来了以下实现keeptags

import Control.Arrow

keeptags g (_,b) = second (g b)

我认为它仍然可读。

于 2012-09-01T10:57:12.783 回答