只替换列表中的元素一次 - Haskell [英] Replace an element in a list only once - Haskell

查看:109
本文介绍了只替换列表中的元素一次 - 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] 

这个类型签名有两点值得注意:


  1. 因为我们可能会停止在列表中部分应用 f ,输入列表和输出列表必须具有相同的类型。 (使用 map ,因为整个列表总是会被映射的,所以类型可以改变。)

  2. 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:

  1. Because we may stop applying f part-way down the list, the input list and the output list must have the same type. (With map, because the entire list will always be mapped, the type can change.)

  2. The type of f hasn't changed to a -> a, but to a -> 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆