LoginSignup
4
2

More than 5 years have passed since last update.

Haskell に python の find みたいなのがない

Last updated at Posted at 2018-11-14

はじめての Qiita 投稿

Haskell の find

Haskell にも Data.Listfind があるのだけど

find :: Foldable t => (a -> Bool) -> t a -> Maybe a

これじゃない。 python の heystack.find('needle') みたいなやつがほしい。

あるかないか

python の find にも使い方がいくつかあると思うが、 needle の有無だけを知りたいなら isInfixOf を使えば良い。

インデックス

Data.List に findIndex とか findIndices とかあるけど求めているものじゃない。

findIndex :: (a -> Bool) -> [a] -> Maybe Int
findIndices :: (a -> Bool) -> [a] -> [Int]

こうかな?

findPython.hs
import Data.Maybe
import Data.List

findPython :: (Eq a) => [a] -> [a] -> Int
findPython needle heystack =
  maybe (-1) fst $ 
  listToMaybe . filter (isPrefixOf needle . snd) $ zip [0 .. ] (tails heystack)

main :: IO ()
main = do
  print $ findPython "abc" "0123456789abcde"
  print $ findPython "xyz" "0123456789abcde"

結果

$ stack runghc findPython.hs
10
-1

インデックス自体は必要ない時

インデックスを見つけるのは目的ではなく、見つけたインデックスの場所に書いてあるものを利用したい、という場合が多いのでは。 needle のインデックスを探すとか、 Haskell っぽくない気がする。

上にも出てくるが、 tails を使うのが Haskell 的なのだろう。

findURL.hs
import Data.Maybe
import Data.List

-- | "https://" を探し、その後が URL であると認識して URL を返す関数
findURL :: String -> Maybe String
findURL s = listToMaybe . filter (isPrefixOf "https://") $ tails s

main :: IO ()
main = do
  print $ findURL "qawsedrfujikolphttps://qiita.com/"

結果

$ stack runghc test2.hs
Just "https://qiita.com/"

References

Data.List -- Hackage

isInfixOf の実装を参考にしました。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2