在 Haskell 中的每个元素中输出带有 Just 的 Maybe Int 列表

Output of a list of Maybe Int with Just in every element in Haskell

我有这个函数,它接受一个整数 n 和 returns 一个 Maybe Int 类型的列表,其中包含唯一的素因子。我不明白为什么它 returns 它们在列表的每个元素中都带有 Just

我希望得到这样的输出:

primeFactors 75 = Just [3,5]

但我有一个看起来像这样的:

primeFactor 75 = [Just 5,Just 3,Just 1]

这是我的代码:

divides :: Int -> Int -> Bool
divides m n = rem m n == 0

transform :: Int -> Int
transform n = (n*2) + 1

isComposite :: Int -> Bool
isComposite n = foldl (||) (divides n 2) (map (divides n) (map (transform) [1..(div n 4)]))

isPrime :: Int -> Bool
isPrime n
 | n <= 0 = error "Makes no sense"
 | n < 4 = True
 | otherwise = not (isComposite n)

primeFactors :: Int -> [Maybe Int]
primeFactors 0 = [Nothing]
primeFactors n = primeFactors2 n ((div n 2)+1)

primeFactors2 :: Int -> Int -> [Maybe Int]
primeFactors2 n 0 = []
primeFactors2 n x
    | divides n x && isPrime x = Just x:primeFactors2 n (x-1)
    | otherwise = primeFactors2 n (x-1)

这是我认为可以满足您要求的代码版本:

primeFactors :: Int -> Maybe [Int]
primeFactors n 
    | n <= 0 = Nothing
    | otherwise = Just $ primeFactors2 n n

primeFactors2 :: Int -> Int -> [Int]
primeFactors2 n p
    | n <= 1 || p <= 1 = []
    | divides n p && isPrime p = p : primeFactors2 (n `div` p) p
    | otherwise = primeFactors2 n (p-1)

isPrime :: Int -> Bool
isPrime n
 | n <= 1 = False
 | otherwise = not (isComposite n)

isComposite :: Int -> Bool
isComposite n = 
    any (divides n) [2..n-1]

divides :: Int -> Int -> Bool
divides m n = 
    rem m n == 0

请注意(为了清楚起见,我希望)我确实删除了您的一些优化并进行了重大更改:此优化将报告 Just [2,2] 作为 4 的主要因素 (IMO 你想要 product <$> primeFactors n == Just n)。

如果不是(如您的示例所示),修复此问题应该不会太难(只需采用您的版本)。

无论如何,唯一真正有趣的贡献是 primeFactor 如何处理 primeFactors2 以获得 Maybe 结果。