2012-08-30 5 views
6

リスト:: [(Foo, Bar)]が与えられていれば、Barでscanl1を実行したいと思いますが、Foo "タグ"を保持しています。"マッピング" scanl

I.e.私はタイプ:: [(a, b)] -> ([b] -> [c]) -> [(a, c)]の関数を使いたいので、2番目の引数としてカーリーscanl1を渡すことができます。

私は再帰的に書くことができますが、これを行うために高次関数を構成する方法があるように感じられます。

これは既に標準機能で可能ですか?

答えて

11

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

を取得する場合。私はそれがまだ読めると思う

import Control.Arrow 

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

+1

クリア、清潔、便利! – amindfv

4

unzip?代わりに不満足な高階関数を書くの、あなたがそうあなたはまだあなたが何を意味するかである、scanl1を使用することができてFooタグをスレッド化するために、あなたの結合機能を持ち上げることができ

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 
+0

それは私を(uncurry zip)(\(a、b) - >(a、scanl1 fb))unzip)まで取得しますが、まだ簡単な方法があるように感じます... – amindfv

+0

私はそうは思わない... – lvella

+0

@イベラ:ありがとう、ありがとう。 – amindfv

2

私の友人はkeeptagsのための次の実装に付属しています。

+0

これはすばらしいです - 清潔でシンプル! – amindfv