はじめての Qiita 投稿
Haskell の find
Haskell にも Data.List
に find
があるのだけど
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
isInfixOf
の実装を参考にしました。