好吧所以这是一个有趣的情况(imo)
这是我的代码:
tails' :: [a] -> [[a]]
tails' [] = []
tails' (x:xs) = tail (x:xs) : tails' xs
inits' :: [a] -> [[a]]
inits' [] = []
inits' (x:xs) = init(x:xs) : inits' xs
eightB :: (Eq a) => [a] -> [a] -> Bool
eightB xs ys = elem xs (tails' ys ++ inits' ys)
我正试图通过向你学习哈斯克尔的大好事来解决“大海捞针”问题;以我自己的方式。
我遇到的问题是,当我尝试输入时:
inits' [1,2,3,4,5]
进入ghci,我得到:
[[1,2,3,4],[2,3,4],[3,4],[4],[]]
该函数在第一次迭代时工作正常,但由于某种原因决定在第一次迭代后切换到尾函数(至少这是我认为发生的事情)。
感谢您的帮助!
编辑:修正了一个拼写错误
答案 0 :(得分:2)
inits' :: [a] -> [[a]]
inits' [] = []
inits' xs = init xs : inits' (init xs)
答案 1 :(得分:1)
我知道这已经有好几年了,但我想我会提到 inits'
对于生成 search
/isInfixOf
函数的实现并不是很有用。上面的代码检查针是否等于尾部之一或初始值之一,而不是它是否包含在某处。现在,如果您出于某种原因确实想计算您的 eightB
函数,那么您可以更便宜地进行计算:
eightB xs ys =
(xs `isPrefixOf'` ys)
|| (reverse xs `isPrefixOf'` reverse ys)
xs `isPrefixOf'` ys = and (zipWith (==) xs ys)
答案 2 :(得分:0)
问题是,tail
中的模式匹配中存在一种固有的inits'
函数。
inits' (x:xs) = ....
这将列表分为两部分
x = head theList
xs = tail theList
当你递归时,你只使用尾部
inits' (x:xs) = <stuff ....> : inits' xs
您真正想要做的是将列表的init
传递给递归。不幸的是,您无法使用模式匹配将列表分解为init
和last
。您可以在where
中轻松完成此操作。
这可能就是你想做的事情
inits' :: [a] -> [[a]]
inits' [] = []
inits' theList = i:inits' i
where
i = init theList
答案 3 :(得分:-1)
在 init
中使用 inits
存在一个巨大的问题,即 init
无法返回任何有意义的或对无限列表正确的内容。
inits
有替代方案
最简单的是
[ [1..i] | i <- [1..] ]
它将永远输出。与它一起使用 take
是明智的。
函数应该接近全函数。
ins ls = [ take i ls | i <- [1..] ]
take 6 $ ins ['a'..]
["a","ab","abc","abcd","abcde","abcdef"]
这些是无限的 tails
函数。第一个,只有数字。第二个,任何。
> tlsn = [ replicate i i | i <- [1..] ]
> tls xs = [ replicate i x |(i,x) <- zip [1..] xs ]
> take 5 tlsn
[[1],[2,2],[3,3,3],[4,4,4,4],[5,5,5,5,5]]
这是tails
和tails
的换位,都是从上到下
1 2 3 4 5 1
2 3 4 5 2 2
3 4 5 3 3 3
4 5 4 4 4 4
5 5 5 5 5 5
> transpose.take 5 $ tlsn
[[1,2,3,4,5],[2,3,4,5],[3,4,5],[4,5],[5]]
transpose
不会转置无限列表。
怎么办?