[英]Haskell wrap function implementation
我对此功能的实现有疑问:
wrap :: Int -> a -> [a] -> [a]
在列表xs
中的第n
个位置插入x
。
wrap 1 '+' "a" : "+a+"
wrap 2 '+' "a" : "+a"
wrap 2 '+' "abcd" : "+ab+cd+"
wrap _ _ [] = []
wrap n x xs = insertAfter 0 xs
where insertAfter = undefined
一个人怎么能做到这一点,我只是想不通。 编辑:
完整的问题:实现函数wrap,该函数将生成一个列表,该列表以wrap的第二个参数(x)开头,然后是wrap的第三个参数(xs)的所有条目,如wrap的第一个参数(n)所示。 重复直到第三个参数为空。 在结果列表中,第n个元素应等于x。 如果xs的长度可以被n整除,请在最后插入x。 提示:根据函数insertAfter来实现函数包装,该函数需要一个数字m和一个元素列表xs,当元素从xs中移除时,m会减少m,并且在m达到0时插入x。
我几乎明白了:
wrap _ _ [] = []
wrap n x xs = insertAfter 0 xs
where insertAfter 0 xs = x : insertAfter n xs
insertAfter _ [] = undefined
insertAfter n xs = take n xs ++ (wrap n x (drop n xs))
但是使用示例:wrap 2'+'“ abcd”:wrap 2'+'“ abcd”:“ + ab + cd +”我得到了“ + ab + cd”,所以缺少了'+'。
我已经自由更改了传递给insertAfter
的参数。 这是非常往往更方便一点倒计时 ,而不是计数 ,并在这里这是事实也是如此。
wrap :: Int -> a -> [a] -> [a]
wrap _ _ [] = []
wrap n delim = insertAfter n
where
-- We've reached zero. So we insert the delimiter and
-- reset the counter to n.
insertAfter 0 xs = delim : insertAfter n xs
-- All done
insertAfter _ [] = ???
-- Still some work to do
insertAfter k (y : ys) = ???
顺便说一句:您所说的“合同”就是我们所说的类型签名 。 实际的合同通常会提供更多有关参数期望值和结果保证值的详细信息。 例如,这里的约定将指定要wrap
的第一个参数必须为正,并解释该函数的作用。
您可以执行以下操作
wrap :: Int -> a -> [a] -> [a]
wrap _ _ [] = []
wrap n c cs | n == length cs = c:cs++[c]
| otherwise = c:x ++ wrap n c y
where (x,y) = splitAt n cs
n == length cs
条件是必需的,因为splitAt 2..n "a"
和splitAt 1 "a"
给出("a","")
。 我也总是假设n >= 1
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.