从Haskell中的列表中删除特定元素

问题描述 投票:1回答:2

我很难将Haskell和函数式编程放在一起。我想要做的是操纵一个字符串,以便每次根据给定的数字打印/返回特定字符。例如:

printing "testing" 2 = "etn"

printing "testing" 3 = "sn"

我在线阅读了很多内容,根据我的理解,我可以通过过滤和循环来实现这一目标,但是我无法获得/理解这种语言的语法来获得一个有效的程序。

haskell functional-programming lazy-evaluation
2个回答
3
投票

我将尝试描述我的思维过程,以便您可以关注。此函数适合通过重复的函数应用程序(此处删除一些元素)从输入种子(此处为字符串)创建输出列表(此处为字符串)的模式。因此,我选择了Data.List.unfoldr的实现。

unfoldr :: (b -> Maybe (a, b)) -> b -> [a]

好吧,我需要将种子b变成(Maybe)输出a和其余的字符串。我将这个子功能称为f并将其传递给unfoldr

printing s n = unfoldr f s
  where f b = case drop n b of
                [] -> Nothing
                (x:xs) -> Just (x,xs)

事实证明,试图将头部从列表前面移开并返回Maybe也是一种常见的模式。这是Data.List.uncons,所以

printing s n = unfoldr (uncons . drop n) s

很顺利!所以我测试出来了,输出错了!实际上你的指定输出例如。对于n=2选择每个第二个字符,即。滴(n-1)字符。

printing s n = unfoldr (uncons . drop (n-1)) s

我再次测试它,它匹配所需的输出。唷!


2
投票

为了向Haskell语言演示一些可接受的答案的替代解决方案。

使用列表理解:

printing :: Int -> String -> String
printing j ls = [s | (i, s) <- zip [1 .. ] ls, mod i j == 0]

使用递归:

printing' :: Int -> String -> String 
printing' n ls 
    | null ls'    = []
    | otherwise   = x : printing' n xs
    where
    ls'         = drop (n - 1) ls
    (x : xs)    = ls' 

在这两种情况下,我都翻转了参数,因此更容易进行部分应用:例如,printing 5是一个新函数,当应用于字符串时将给出每个第5个字符。

注意稍作修改,它们适用于任何列表

takeEvery :: Int -> [a] -> [a]
© www.soinside.com 2019 - 2024. All rights reserved.