假設我想iterate step x0在 Haskell 中構建一個串列,但具有包含終止條件。所以在 Python 中,這將是list(my_gen)例如
def my_gen():
x = x0
while not done(x):
x = step(x)
yield x
(編輯:yield x如果我想包括,這應該在回圈之前有一個額外的x0。)
一種方法是撰寫我自己的takeWhileInclusive并說
takeWhileInclusive (not . done) . iterate step x0
這是哈斯克爾-Y方式(或一哈斯克爾-Y方式)來做到這一點?嘗試在step xwhendone x為 true時添加一些標記值然后使用takeWhile.
特別是我在考慮LeetCode 上有最多水問題的容器,并用類似的方法解決它
maxWith volume . smartSteps (0, n)
where smartSteps = takeWhileInclusive (\(i,j) -> j - i > 1) . iterate step
和step增加i或減少j(或兩者),根據哪個指數具有更高的線。
當然,在這里只使用takeWhilej > i會很容易,但我想考慮如何處理沒有自然“你走得太遠”條件,只有“你已經完成”條件的情況。
編輯:這個問題已經被標記為(一的重復問題,我曾掛在我的問題),但事實并非如此。問題不在于如何寫takeWhileInclusive,實際上問題明確地takeWhileInclusive視為給定。它是關于如何完成一項可能會或可能不會使用的任務takeWhileInclusive。
uj5u.com熱心網友回復:
您可以使用unfoldr來生成序列:
unfoldr (\x -> if done x then Nothing else Just (x, step x)) x0
例如,
> 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]
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))
uj5u.com熱心網友回復:
是的,這是一種 Haskell-y 方式。
另一種 Haskell-y 方法(或 Haskell-y 實作方法takeWhileInclusive)是在iterate一步之后壓縮d 值。
myGen done step = map snd . takeWhile (not . done . fst) . ap zip tail . iterate step
NB 不像iterate(但像my_gen)這不會將初始x值作為步驟之一發出。
uj5u.com熱心網友回復:
你可以定義
takeUntil done xs =
foldr (\x r -> if done x then [x] else x : r) [] xs
然后像這樣使用它
takeUntil done $ iterate step x0
例如takeUntil (> 9) [1..] == [1..10]。
指定最終元素很容易foldr(如此處所見),但更麻煩的是unfoldr編碼“變形”,用空串列作為標記關閉生成的串列。使用“apomorphism”可以指定非空尾部,這似乎是此任務的擬合工具。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/387041.html
上一篇:使用由函子引數化的資料型別
下一篇:訪問Ziplist中的位置
