简体   繁体   English

在 Haskell 中创建初始化函数

[英]Making inits function in Haskell

Alright so here is an interesting situation (imo)好吧,这是一个有趣的情况(imo)

Here's my code:这是我的代码:

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)

I'm trying to solve the "Needle in a Haystack" problem from Learn You a Haskell For Great Good;我正在尝试解决 Learn You a Haskell For Great Good 中的“大海捞针”问题; in my own way.以我自己的方式。

The problem I'm running into is, when I try inputting:我遇到的问题是,当我尝试输入时:

inits' [1,2,3,4,5]

into ghci, I get:进入ghci,我得到:

[[1,2,3,4],[2,3,4],[3,4],[4],[]]

The function works fine for the first iteration, but for some reason decides to switch to the tail function after the first iteration (at least that's what I think is happening).该函数在第一次迭代时运行良好,但出于某种原因决定在第一次迭代后切换到 tail 函数(至少我认为正在发生)。

@Iuqui helped me get to this answer. @Iuqui 帮助我得到了这个答案。

inits' :: [a] -> [[a]]
inits' [] = []
inits' xs = init xs : inits' (init xs)

I know this is several years old, but figured I'd mention that inits' is not really useful for producing an implementation of the search / isInfixOf function.我知道这已经有好几年了,但我想我会提到inits'对于生成search / isInfixOf函数的实现并不是很有用。 Your code above checks to see whether the needle is equal to one of the tails or one of the inits, not whether it's contained somewhere.上面的代码检查针是否等于尾部之一或初始值之一,而不是它是否包含在某处。 Now if you actually do want to calculate your eightB function for some reason, you can do so much more cheaply:现在,如果您出于某种原因确实想计算您的eightB函数,您可以更便宜地进行计算:

eightB xs ys =
  (xs `isPrefixOf'` ys)
  || (reverse xs `isPrefixOf'` reverse ys)

xs `isPrefixOf'` ys = and (zipWith (==) xs ys)

The problem is, there is a sort of inherent tail function in your pattern matching in inits' .问题是,在inits'中的模式匹配中有一种固有的tail函数。

inits' (x:xs) = ....

This breaks up the list into two parts这将列表分为两部分

x = head theList
xs = tail theList

When you recurse, you are only using the tail part当您递归时,您只使用尾部

inits' (x:xs) = <stuff ....> : inits' xs

What you really want to do is pass the init of the list into the recursion.您真正想要做的是将列表的init传递到递归中。 Unfortunately, you can't break up a list into init and last using pattern matching.不幸的是,您不能使用模式匹配将列表分解为initlast You can do this easily in a where though.不过,您可以在某个where轻松完成此操作。

This is probably what you want to do这可能是你想要做的

inits' :: [a] -> [[a]]
inits' [] = []
inits' theList = i:inits' i
  where
    i = init theList

There is one huge problem with using init in inits , that is, init cannot return anything meaningful nor correct with an infinite list.inits使用init存在一个巨大的问题,即init无法返回任何有意义或正确的无限列表。

There are alternatives for inits inits有替代方案

The simplest is最简单的是

[ [1..i] | i <- [1..] ]

It will output forever.它将永远输出。 It is wise to use take with it.这是明智的使用take它。

Functions should approach total functions.函数应该接近全函数。

ins ls = [ take i ls | i <- [1..] ]

take 6 $ ins ['a'..]
["a","ab","abc","abcd","abcde","abcdef"]

These are infinite tails functions.这些是无限tails函数。 The first, numbers only.第一个,只有数字。 The second, any.第二,任何。

> 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]]

This is tails and a transposition of tails , both from top to bottom这是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 will not transpose an infinite list. transpose不会转置一个无限列表。

What to do?该怎么办?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM