只替换列表中的元素一次 - Haskell [英] Replace an element in a list only once - Haskell
问题描述
我想仅在第一次出现时用新值替换列表中的元素。
我写了下面的代码,但是使用它,所有匹配的元素都会改变。
replaceX :: [Int] - > Int - > Int - > [Int]
replaceX items old new = map检查项目,其中
检查项目| item == old = new
|否则= item
如何修改代码,以便只在第一个匹配项目发生更改?
感谢您的帮助!
关键是<$ c在你的例子中,$ c> map 和 f
( check
)只交流关于如何转换个别元素。他们并没有就如何转换元素进行沟通: map
总是一直持续到最后。
map ::(a - > b) - > [a] - > [b]
map _ [] = []
map f(x:xs)= fx:map f xs
让我们写一个新版本的 map
---我将它称为 mapOnce
因为我想不出一个更好的名字。
mapOnce ::(a - >也许a) - > ; [a] - > [b]
这个类型签名有两点值得注意:
-
因为我们可能会停止在列表中部分应用
f
,输入列表和输出列表必须具有相同的类型。 (使用map
,因为整个列表总是会被映射的,所以类型可以改变。)
-
f
的类型尚未更改为a - > a
,但是到a - >也许是一个
。
-
Nothing
这个元素不变,继续下去 -
只要y
意味着改变这个元素,并保留其余元素不变 / li>
-
所以:
mapOnce _ [] = []
mapOnce f(x:xs)=
的情况fx Nothing - > x:mapOnce f xs
Just y - > y:xs
您的示例现在是:
replaceX :: [Int] - > Int - > Int - > [Int]
replaceX items old new = mapOnce检查项目,其中
检查项目| item == old =只是新的
|否则= Nothing
I want to replace an element in a list with a new value only at first time occurrence. I wrote the code below but using it, all the matched elements will change.
replaceX :: [Int] -> Int -> Int -> [Int]
replaceX items old new = map check items where
check item | item == old = new
| otherwise = item
How can I modify the code so that the changing only happen at first matched item?
Thanks for helping!
The point is that map
and f
(check
in your example) only communicate regarding how to transform individual elements. They don't communicate about how far down the list to transform elements: map
always carries on all the way to the end.
map :: (a -> b) -> [a] -> [b]
map _ [] = []
map f (x:xs) = f x : map f xs
Let's write a new version of map
--- I'll call it mapOnce
because I can't think of a better name.
mapOnce :: (a -> Maybe a) -> [a] -> [a]
There are two things to note about this type signature:
Because we may stop applying
f
part-way down the list, the input list and the output list must have the same type. (Withmap
, because the entire list will always be mapped, the type can change.)The type of
f
hasn't changed toa -> a
, but toa -> Maybe a
.Nothing
will mean "leave this element unchanged, continue down the list"Just y
will mean "change this element, and leave the remaining elements unaltered"
So:
mapOnce _ [] = []
mapOnce f (x:xs) = case f x of
Nothing -> x : mapOnce f xs
Just y -> y : xs
Your example is now:
replaceX :: [Int] -> Int -> Int -> [Int]
replaceX items old new = mapOnce check items where
check item | item == old = Just new
| otherwise = Nothing
这篇关于只替换列表中的元素一次 - Haskell的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!