递归函数
我在练习中遇到问题,我应该定义一个函数,该函数将整数、字符和字符串作为输入,并返回将字符放入字符串中整数指定的位置的结果,例如,给出 3
、'a'
和 "haskell"
到该函数应生成 "hasakell"
。
putinto :: Int -> Char -> String -> String
putinto
I am having trouble with an exercise where I should define a function which takes as input an integer, a character and a string and returns the result of putting the character in the string at the position specified by the integer, for example, giving 3
, 'a'
and "haskell"
to the function should result in "hasakell"
.
putinto :: Int -> Char -> String -> String
putinto
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这样想:有一个列表,其中第一个元素称为“x”,列表的其余部分称为“xs”(在 Haskell 中,这将写为
(x:xs)
),您要么将给定值添加到位置为 0 的列表中。否则,您将在列表的其余部分递归地调用自己(并减少位置)。如果看起来很奇怪,
(x:xs)
实际上是一个“解构”列表。x
表示列表的第一个元素,xs
(“s”表示“复数”,因此它是“x”的复数)是列表的其余部分。因此,用零调用它实际上会在给定值前面加上给定值,就像用
两个调用它一样:
不过,您仍然需要关心错误检查(如果给定位置为负数或大于列表长度怎么办?)。
Think about it this way: having a list where the first element is called 'x' and the rest of the list is called 'xs' (in Haskell, this would be written as
(x:xs)
), you either prepend your given value to the list of the position is 0. Otherwise you call yourself recursively on the remained of the list (and decrease the poisition).In case it looks odd, the
(x:xs)
is actually a "deconstructed" list. Thex
represents the first element of the list,xs
(the 's' means 'plural', so it's the plural of 'x') is the rest of the list.So calling it with a zero will actually prepend the given value, as in
Calling it with two will be:
You still need to care about error checking (what if the given position is negative, or larger than the list length?) though.
这在 C# 中可以解决问题
this wil do the trick in C#
在为 Haskell 中涉及列表的问题编写显式递归解决方案之前,值得检查一下是否可以使用
Prelude
或Data.List
。在这种情况下splitAt
可以提供帮助:因此,您的问题可以通过拆分、consing 和附加轻松解决:
只是为了好玩,上面的内容也可以使用
的应用实例以无点风格编写>(->r)
:Before writing an explicitly recursive solution to a problem involving lists in Haskell, it's worth checking to see if the same task can be accomplished using the list functions in the
Prelude
orData.List
. In this casesplitAt
can help:Thus your problem is easily solved by splitting, consing and appending:
Just for fun, the above can also be written in a point-free style using the applicative instance for
(-> r)
:我认为这应该很容易阅读。我列举了几行来解释:
这里发生了什么?第一行是类型签名。第二行检查您是否希望将字符设置在前面(即索引 0)。
第三行和第四行适用于我们希望将其插入到第 0 个索引之后的情况。第三行检查我们要插入的列表是否为空,在这种情况下我们只返回仅包含
a
的列表。在第四行中,我们知道字符串的第一个索引仍然是第一个,因此我们只是在尾部递归,沿途根据需要减少
n
。I think this should be fairly easy to read. I enumerated the lines for explanation:
What goes on here? The first line is the type signature. The second line checks if you wish to set the character at the front (ie. index 0).
The third and fourth line is for when we wish to insert it later than the 0'th index. The third line checks if the list we want to insert into is empty, in which case we just return the list containing only
a
.In the fourth line we know that the first index of our string will still be the first, so we just recurse on the tail, decreasing
n
as needed along the way.