我很难把Haskell和函数式编程结合在一起。我想做的是操纵一个字符串,以便每次根据给定的数字打印/返回特定字符。例如:
printing "testing" 2 = "etn"
printing "testing" 3 = "sn"
我已经在网上阅读了很多东西,据我了解,我可以通过过滤和循环来实现这一点,但是我无法理解这种语言的语法来获得一个有效的程序。
答案 0 :(得分: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
我再次对其进行测试,它与所需的输出匹配。 ew!
答案 1 :(得分: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]