haskell - 如何在 Haskell 的列表理解中有条件地模式匹配

标签 haskell list-comprehension monads

我想写这样的东西:

> [(i, j) | i <- [1..10], 
            Just j <- [if (even i) then Just (i `div` 2) else Nothing]]
[(2,1),(4,2),(6,3),(8,4),(10,5)]

将条件放入列表并使用 <-提取结果似乎是临时的。

我试过:
> [(i, j) | i <- [1..10], 
            let Just j = if (even i) then Just (i `div` 2) else Nothing]

但那失败了。

以下工作但似乎很尴尬:
> [(i, j) | i <- [1..10], 
            let x = if (even i) then Just (i `div` 2) else Nothing, 
            isJust x, 
            let Just j = x]
[(2,1),(4,2),(6,3),(8,4),(10,5)]

有没有首选的方法来做到这一点。

我知道这个特定问题可以通过其他方式解决,但让我们假设我想在列表理解中有条件地进行模式匹配。 有没有好的方法可以做到这一点?

谢谢。

最佳答案

这对你来说可以接受吗?

[(i, j) | i <- [1..10], even i, let j = i `div` 2]

另一个(IMO 更糟)选项:
[(i, j) | i <- [1..10], 
          j <- if even i then [i `div` 2] else []]

完后还有:
do i <- [1..10]
   j <- guard (even i) >> return (i `div` 2)
   return (i,j)

完后还有:
[(i, j) | i <- [1..10], 
          j <- [i `div` 2 | even i]]

真的矫枉过正,强烈不推荐:
{-# LANGUAGE PatternSynonyms, ViewPatterns #-}

testEvenRight :: Integral a => Either b a -> Maybe a
testEvenRight (Right n) | even n = Just n
testEvenRight _                  = Nothing

pattern EvenRight n <- (testEvenRight -> Just n)

list1 = [Right 2, Right 1, Left "abc", Right 4, Right 5]

list2 = [(i,j) | EvenRight i <- list1 , let j = i `div` 2]

关于haskell - 如何在 Haskell 的列表理解中有条件地模式匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40590229/

相关文章:

scala - 用 For-Comprehension 重写模式匹配

haskell - (>>=) 和 (>=>) 之间的区别

haskell - 用 Haskell 编写 Haskell 解释器

haskell - 如何使用管道检测输入结束

python - 列表推导式中定义的变量是否会泄漏到封闭范围中?

python - 如何在 python 中扩展字符串中的字符串?

haskell - 如何在 Yesod 的组合 javascript 文件中对 Julius 文件进行排序?

haskell - 交错列表函数

从嵌套字典生成列表的 Pythonic 方法

haskell - 一个简单的例子表明 IO 不满足单子(monad)定律?