gpt4 book ai didi

loops - Haskell:有条件地中断循环

转载 作者:行者123 更新时间:2023-12-04 16:39:19 25 4
gpt4 key购买 nike

我想在这样的情况下打破一个循环:

import Data.Maybe (fromJust, isJust, Maybe(Just))

tryCombination :: Int -> Int -> Maybe String
tryCombination x y
| x * y == 20 = Just "Okay"
| otherwise = Nothing

result :: [String]
result = map (fromJust) $
filter (isJust) [tryCombination x y | x <- [1..5], y <- [1..5]]

main = putStrLn $ unlines $result

想象一下,“tryCombination”比这个例子复杂得多。而且它消耗了大量的CPU功率。这不是对 25 种可能性的评估,而是 26^3。

因此,当“tryCombination”找到给定组合的解决方案时,它返回一个 Just,否则返回一个 Nothing。如何在第一个找到的解决方案上立即打破循环?

最佳答案

简单的解决方案:findjoin
看起来您正在寻找 Data.List.find . find有类型签名

find :: (a -> Bool) -> [a] -> Maybe a

所以你会做类似的事情
result :: Maybe (Maybe String)
result = find isJust [tryCombination x y | x <- [1..5], y <- [1..5]]

或者,如果您不想要 Maybe (Maybe String) (你为什么要这样做?),你可以用 Control.Monad.join 把它们折叠起来。 , 有签名
join :: Maybe (Maybe a) -> Maybe a

所以你有
result :: Maybe String
result = join $ find isJust [tryCombination x y | x <- [1..5], y <- [1..5]]

更高级的解决方案: asum
如果您想要更高级的解决方案,可以使用 Data.Foldable.asum , 有签名
asum :: [Maybe a] -> Maybe a

它的作用是挑出第一个 Just值来自许多列表。它通过使用 Alternative 来做到这一点。 Maybe 的实例. Alternative Maybe 的实例工作方式如下:(导入 Control.Applicative 以访问 <|> 运算符)
λ> Nothing <|> Nothing
Nothing
λ> Nothing <|> Just "world"
Just "world"
λ> Just "hello" <|> Just "world"
Just "hello"

换句话说,它选择第一个 Just两种选择的值(value)。想象把 <|>在列表的每个元素之间,以便
[Nothing, Nothing, Just "okay", Nothing, Nothing, Nothing, Just "okay"]

被转向
Nothing <|> Nothing <|> Just "okay" <|> Nothing <|> Nothing <|> Nothing <|> Just "okay"

这正是 asum功能呢!自 <|>短路,它只会评估第一个 Just值(value)。有了这个,你的功能就会很简单
result :: Maybe String
result = asum [tryCombination x y | x <- [1..5], y <- [1..5]]

你为什么想要这个更高级的解决方案?它不仅更短;一旦你知道了这个习惯用法(即当你熟悉 Alternativeasum 时),只需阅读代码的前几个字符,就可以更清楚地了解函数的作用。

关于loops - Haskell:有条件地中断循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29648319/

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