Hatena::Grouphaskell

Haskellで遊ぶよ

 | 

2009-06-11

takeWhile2とdropWhile2

00:46

takeWhile               :: (a -> Bool) -> [a] -> [a]
takeWhile p []          =  []
takeWhile p (x:xs) 
            | p x       =  x : takeWhile p xs
            | otherwise =  []

dropWhile               :: (a -> Bool) -> [a] -> [a]
dropWhile p []          =  []
dropWhile p xs@(x:xs')
            | p x       =  dropWhile p xs'
            | otherwise =  xs

これを参考に、リストのある要素と、その次の要素の2つを引数に取る関数を作る。

takeWhile2              :: (a -> a -> Bool) -> [a] -> [a]
takeWhile2 p []         =  []
takeWhile2 p (_:[])     =  []
takeWhile2 p (x:x':xs')
            | p x x'    =  x : (takeWhile2 p (x':xs'))
            | otherwise =  []

dropWhile2              :: (a -> a -> Bool) -> [a] -> [a]
dropWhile2 p []         =  []
dropWhile2 p (_:[])     =  []
dropWhile2 p xs@(x:x':xs')
            | p x x'    =  dropWhile2 p (x':xs')
            | otherwise =  xs

こういうことがやりたかったので。

Main> takeWhile2 (\x y -> y-x<50) $ dropWhile2 (\x y -> y-x<10) $ map (^2) [1..]
[25,36,49,64,81,100,121,144,169,196,225,256,289,324,361,400,441,484,529,576,625]

学んだこと

xs@(x:xs')

全体としてパターン xs、部分としてパターン x:xs' にマッチする引数。


前の要素と比べる

ただ、takeWhile2でちょっと悩ましいのはtakeされるのが 評価関数の第一パラメタにわたる値なのか大にパラメタにわたる値なのか、どっちがいいのかは結構その場その場で変わってきそうなところのような気もしますね…

ずらしてみよう - 取り急ぎブログです

ごもっともです。

takeWhile2'             :: (a -> a -> Bool) -> [a] -> [a]
takeWhile2' p []        =  []
takeWhile2' p (_:[])    =  []
takeWhile2' p (x:x':xs')
            | p x x'    =  x : (takeWhile2' p (x':xs'))
            | otherwise =  [x]

dropWhile2'             :: (a -> a -> Bool) -> [a] -> [a]
dropWhile2' p []        =  []
dropWhile2' p (_:[])    =  []
dropWhile2' p xs@(x:x':xs')
            | p x x'    =  dropWhile2' p (x':xs')
            | otherwise =  x':xs'
Main> takeWhile2 (\x y -> y-x<20) $ dropWhile2 (\x y -> y-x<10) $ scanl1 (+) [1..]
[45,55,66,78,91,105,120,136,153,171]
Main> takeWhile2' (\x y -> y-x<20) $ dropWhile2' (\x y -> y-x<10) $ scanl1 (+) [1..]
[55,66,78,91,105,120,136,153,171,190]

(最初に書いてたやつはちょっと末端がおかしかったので密かに修正)

トラックバック - http://haskell.g.hatena.ne.jp/edvakf/20090611
 |