我想写这样的东西:
> [(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/