2

これは非常に一般的な操作のようですが、何らかの理由で hoogle で見つけることができません。いずれにせよ、これは興味深い思考練習です。私の素朴な実装:

pluckL :: [a] -> Int -> Maybe ( a, [a] )
pluckL xs idx = if idx < length xs then Just $ pluck' xs idx else Nothing
where
    pluck' l n = let subl = drop n l in ( head subl, rest l n ++ tail subl )
    rest   l n = reverse $ drop ( length l - n ) $ reverse l

私の主な不満は、リストを何度もめくっていることです。そのため、リストを 1 回トラバースしてタプルを生成できる創造的な方法を探しています。

4

3 に答える 3

7

効率的な方法は決してありません。しかし、少なくともきれいな方法がある可能性があります:

pluckL xs i = case splitAt i xs of
    (b, v:e) -> Just (v, b ++ e)
    _ -> Nothing
于 2013-03-10T15:50:52.590 に答える
1

reverseアキュムレータを使用すると、リストの操作を 1 つ少なくするだけで済みます。

pluckL :: [a] -> Int -> Maybe (a, [a])
pluckL xs idx = pluck xs idx [] where
    pluck (x:xs) 0 acc = Just $ ( x, (reverse acc) ++ xs )
    pluck (x:xs) i acc = pluck xs (i-1) (x:acc)
    pluck [] i acc = Nothing
于 2013-03-10T15:48:20.617 に答える
1

elemを使用して elem がリストにあるかどうかを確認し、結果に応じて Nothing を返すか、delete xを使用してリストから x を削除します。たとえば、次のようになります。

pluckL :: Eq a => [a] -> a -> Maybe (a, [a]) 
pluckL xs0 x =  
    if (x `elem` xs0) 
    then Just (x, xs) 
    else Nothing
        where xs = delete x xs0
于 2013-03-10T15:51:18.770 に答える