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

标签 loops haskell break

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

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/

相关文章:

haskell - 打印一些东西的递归函数

haskell - 获取嵌套列表的头和尾

haskell - 由于垃圾收集,Haskell 程序中会出现多长时间的暂停?

Java,在字符r之前截断数组行。 X

c - Break 语句会跳出 while 循环和另一个 if 循环吗?

javascript - 从数组中创建新元素,直到数组每秒为空

vba - VBA中的大循环崩溃

javascript - 无论大写,检查对象中的匹配键

python - 如何迭代类属性而不是函数并在 python 中返回属性值?

bash - 阅读docker事件时,如何退出docker事件而不是整个程序?