Eri*_*uld 3 haskell functional-programming generator
假设我想iterate step x0
在 Haskell 中构建一个列表,但具有包含终止条件。所以在Python中这将是list(my_gen)
例如
def my_gen():
x = x0
while not done(x):
x = step(x)
yield x
Run Code Online (Sandbox Code Playgroud)
(编辑:如果我想包含,这应该yield x
在循环之前有一个额外的x0
。)
一种方法是编写我自己的takeWhileInclusive并说
takeWhileInclusive (not . done) . iterate step x0
Run Code Online (Sandbox Code Playgroud)
这是实现此目的的Haskell-y 方式(或Haskell -y 方式)吗?step x
尝试为何时为真添加一些哨兵值done x
然后使用似乎不自然takeWhile
。
特别是我正在考虑LeetCode上水问题最多的容器,并用类似的方法解决它
maxWith volume . smartSteps (0, n)
where smartSteps = takeWhileInclusive (\(i,j) -> j - i > 1) . iterate step
Run Code Online (Sandbox Code Playgroud)
并step
增加i
或减少j
(或两者),根据哪个指数具有较高的线。
当然,在这里使用 j > i 很容易takeWhile
,但我想考虑如何处理不存在自然的“你走得太远”条件,而只是“你已经完成”条件的情况。
编辑:这个问题已被标记为重复(我在问题中链接到的问题),但事实并非如此。问题不是如何写takeWhileInclusive
,事实上问题明确地认为takeWhileInclusive
是给定的。它是关于如何完成可能使用也可能不使用的任务takeWhileInclusive
。
您可以使用unfoldr
来生成序列:
unfoldr (\x -> if done x then Nothing else Just (x, step x)) x0
Run Code Online (Sandbox Code Playgroud)
例如,
> import Data.List
> step = (+1)
> done = (> 10)
> x0 = 0
> unfoldr (\x -> if done x then Nothing else Just (x, step x)) x0
[0,1,2,3,4,5,6,7,8,9,10]
Run Code Online (Sandbox Code Playgroud)
unfoldr
调用其函数x0
来启动。当函数返回时Nothing
,unfoldr
停止。当函数返回时Just (x, y)
,它会追加x
到结果中并再次调用该函数y
。
将您的生成器与 Python 实现进行比较unfoldr
:
def unfoldr(f, x):
while True:
if (y := f(x)) is None:
return
else:
yield y[0]
x = y[1]
list(unfoldr(lambda x: None if done(x) else (x, step(x)), x0))
Run Code Online (Sandbox Code Playgroud)