gpt4 book ai didi

function - 如何在 Haskell 中继续调用具有不同参数的函数直到成功

转载 作者:行者123 更新时间:2023-12-03 06:44:33 24 4
gpt4 key购买 nike

我有一个函数调用另一个函数,该函数可以根据某些条件返回某些内容或不返回任何内容。我想知道的是,如果它什么也没返回,我该如何用不同的参数再次调用它。

例如,我有一个函数可以以 30 分钟为间隔返回时间,而另一个函数只能在特定时间不返回任何内容,即:

certainTimeFunction :: (Int,Int,Int) -> Maybe String
certainTimeFunction (h,m,s) =
| (11,00,00) = Just "It's eleven o'clock"
| otherwise = Nothing

timeFunction :: (Int,Int,Int) -> (Int,Int,Int)
timeFunction time = certainTimeFunction time

时间必须从 (00,00,00) 开始,这当然会返回 Nothing,但是尝试 (00,30,00) 再次返回 Nothing,直到 (11,00,00) 触发该函数返回第一个守卫中的内容,然后整个循环应该结束。

最佳答案

与 Haskell 中一样,答案是使用递归!

timeFunction :: (Int, Int, Int) -> (Int, Int, Int)
timeFunction time0 = case certainTimeFunction time0 of
Nothing -> timeFunction (perturbTime time0)
Just res -> res

请注意,应仔细调整 perturbTimecertainTimeFunction 以便协同工作,因为在这种情况下很容易构建无限循环。一种更简洁的方法是使用iterate将递归“展开”到惰性列表中。

首先我们创建一个“所有扰动”的无限列表

... iterate perturbTime :: [(Int, Int, Int)]

然后我们映射 certainTimeFunction来检查是否有任何此类扰动返回Just

... map certainTimeFunction . iterate perturbTime :: [Maybe (Int, Int, Int)]

然后我们可以通过删除所有 Nothing 来恢复 timeFunction 的确切行为。

timeFunction = fromJust . head . dropWhile isNothing 
. map certainTimeFunction
. iterate perturbTime

我们还可以创建一个 timeFunction 版本,如果 perturbTimen 个扰动内未达到成功点,该版本就会失败

timeFunctionN n = safeJustHead 
. dropWhile isNothing
. take n
. map certainTimeFunction
. iterate perturbTime
where safeJustHead :: [Maybe a] -> Maybe a -- note this is just `msum`
safeJustHead [] = Nothing -- it's also easy to implement
safeJustHead (x:_) = x -- using `Data.Maybe.listToMaybe`
-- per @bheklilr's comment below

关于function - 如何在 Haskell 中继续调用具有不同参数的函数直到成功,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20747830/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com