2017-11-22 7 views
-7

リストの1つの要素にのみ関数を適用するにはどうすればよいですか? 提案がありますか?リストの特定の要素に関数を適用する方法

例:

let list = [1,2,3,4,3,6] 
    function x = x * 2 
in ... 

私はわずか3の最初のoccuranceにfunctionを適用し、そこに停止します。

出力:

List = [1,2,6,4,3,6] -- [1, 2, function 3, 4, 3, 6] 
+0

あなたの側にどんな試みを次のように動作します

map_one_element :: (Eq a, Num a) => a -> (a -> a) -> [a] -> [a] -- base case map_one_element _ _ [] = [] -- recursive case map_one_element x f (y:ys) -- ff element is found, apply f to it and add rest of the list normally | x == y = f y : ys -- first occurence hasnt been found, keep recursing | otherwise = y : map_one_element x f ys 

を? –

+1

さらに、リストに2つ(またはそれ以上)が3つある場合はどうなりますか? –

+0

これはIntのリストです! – JohnnyPire

答えて

0

あなたはmapは、すべての値に関数を適用するために、値の最初のインスタンスを示すために、状態のいくつかの種類を維持する必要があります。おそらく、

この

map (\(b,x) -> if (b) then f x else x) $ markFirst 3 [1,2,3,4,3,6] 

markFirst :: a -> [a] -> [(Boolean,a)] 
markFirst a [] = [] 
markFirst a (x:xs) | x==a = (True,x): zip (repeat False) xs 
        | otherwise = (False,x): markFirst a xs 

のようなもの、私はもっと簡単な方法があると確信しているが、それは私が感謝祭の前日に、この時点で思い付いたのが最善です。ここで

をマッピングするためにマッピングするかしないかを

> let leftap f (x,y) = f x ++ y 

leftap (map (\x -> if(x==3) then f x else x)) $ splitAt 3 [1,2,3,4,3,6] 
0

以下のコメントに基づいて別のアプローチである、それが問題です。

地図を表示しないようにしてください。

なぜですか?とにかくmap id == idだから、という1つの要素を使ってマップしたいだけです。最初のものは与えられた引数と等しいと分かります。

したがって、リストを2つに分割し、見つかった要素を変更して、それらをすべてまとめて接着します。シンプル。

参照:span :: (a -> Bool) -> [a] -> ([a], [a])

書き込み:revappend (xs :: [a]) (ys :: [a]) == append (reverse xs) ys、効率的です。

または、すべての要素を1つの機能にまとめます。手動再帰を使用して直接コード化することも、foldrを使用してコード化することもできます。あなたが(\x xs r -> ...)多様の結合機能を必要とするようfoldrは、直接のフィットではありません、が、

map f xs = foldr (\x r -> f x : r) [] xs 

takeWhile p xs = foldr (\x r -> if p x then x : r else []) [] xs 

takeUntil p xs = foldr (\x r -> if p x then [x] else x : r) [] xs 

filter p xs = foldr (\x r -> if p x then x : r else r) [] xs 

duplicate xs = foldr (\x r -> x : x : r) [] xs 

mapFirstThat p f xs = -- ... your function 

などを覚えておいてください。これは、パラモフィスとして知られており、代わりにをfoldrに供給することによってcan be fakedになります。

0

あなたはわずか2によってその倍数の数を単純な関数を作成することができます。

times_two :: (Num a) => a -> a 
times_two x = x * 2 

そして、単にリスト内の指定された要素を検索し、それにtimes_twoを適用します。このような何かは仕事ができる:

*Main> map_one_element 3 times_two [1,2,3,4,3,6] 
[1,2,6,4,3,6] 
関連する問題