在 Haskell 中实现哥德巴赫猜想,很多限制
Implementing Goldbach's conjecture in Haskell, lots of restrictions
这项作业的重点是理解列表理解。
使用几个预定义的函数并在以下限制下对某个自然数实现哥德巴赫猜想(否则行为无关紧要):
- 无辅助功能
- 不使用 where 或 let
- 左侧和右侧只有一个定义方程必须是列表理解
- 结果列表中对的顺序无关紧要
- 允许使用 Prelude 中的函数
-- This part is the "library"
dm :: Int -> [ Int ] -> [ Int ]
dm x xs = [ y | y <- xs , y `mod ` x /= 0]
da :: [ Int ] -> [ Int ]
da ( x : xs ) = x : da ( dm x xs )
primes :: [ Int ]
primes = da [2 ..]
-- Here is my code
goldbach :: Int -> [(Int,Int)]
-- This is my attempt 1
goldbach n = [(a, b) | n = a + b, a <- primes, b <- primes, a < n, b < n]
-- This is my attempt 2
goldbach n = [(a, b) | n = a + b, a <- takeWhile (<n) primes, b <- takeWhile (<n) primes]
预期结果:所有对的列表,总和为指定整数。但是 GHC 抱怨说在理解中,n 是未知的。我的直觉告诉我我需要一些 Prelude 函数来实现我需要的功能,但是哪个?
更新
parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let n = 5' instead of 'n = 5'
抛开你所说的奇怪错误,我认为你实际遇到的问题如下:
正如@chi和我所提到的,在定义a和b之前,您不能在最终理解中使用a和b。
所以你必须把它移到 and.
此外:在 haskell 中使用 (==)
而非 (=)
检查整数是否相等。
所以你也需要改变它。
这将是您最终方法的完整代码:
goldbach n = [(a, b) | a <- takeWhile (<n) primes, b <- takeWhile (<n) primes, n == a + b]
一个小测试产生:
*Main> goldbach 5
[(2,3),(3,2)]
更新
如果你想实现你在评论中写的,你可以在你的理解中添加另一个条件
n `mod` 2 == 0
甚至更好:用这样的守卫定义你的函数:
goldbach n
| n `mod` 2 == 0 = [(a, b) | a <- takeWhile (<n) primes, b <- takeWhile (<n) primes, n == a + b]
| otherwise = []
但是,如果我没记错的话,这与实际的哥德巴赫猜想无关。
这项作业的重点是理解列表理解。
使用几个预定义的函数并在以下限制下对某个自然数实现哥德巴赫猜想(否则行为无关紧要):
- 无辅助功能
- 不使用 where 或 let
- 左侧和右侧只有一个定义方程必须是列表理解
- 结果列表中对的顺序无关紧要
- 允许使用 Prelude 中的函数
-- This part is the "library"
dm :: Int -> [ Int ] -> [ Int ]
dm x xs = [ y | y <- xs , y `mod ` x /= 0]
da :: [ Int ] -> [ Int ]
da ( x : xs ) = x : da ( dm x xs )
primes :: [ Int ]
primes = da [2 ..]
-- Here is my code
goldbach :: Int -> [(Int,Int)]
-- This is my attempt 1
goldbach n = [(a, b) | n = a + b, a <- primes, b <- primes, a < n, b < n]
-- This is my attempt 2
goldbach n = [(a, b) | n = a + b, a <- takeWhile (<n) primes, b <- takeWhile (<n) primes]
预期结果:所有对的列表,总和为指定整数。但是 GHC 抱怨说在理解中,n 是未知的。我的直觉告诉我我需要一些 Prelude 函数来实现我需要的功能,但是哪个?
更新
parse error on input ‘=’
Perhaps you need a 'let' in a 'do' block?
e.g. 'let n = 5' instead of 'n = 5'
抛开你所说的奇怪错误,我认为你实际遇到的问题如下:
正如@chi和我所提到的,在定义a和b之前,您不能在最终理解中使用a和b。 所以你必须把它移到 and.
此外:在 haskell 中使用 (==)
而非 (=)
检查整数是否相等。
所以你也需要改变它。
这将是您最终方法的完整代码:
goldbach n = [(a, b) | a <- takeWhile (<n) primes, b <- takeWhile (<n) primes, n == a + b]
一个小测试产生:
*Main> goldbach 5
[(2,3),(3,2)]
更新
如果你想实现你在评论中写的,你可以在你的理解中添加另一个条件
n `mod` 2 == 0
甚至更好:用这样的守卫定义你的函数:
goldbach n
| n `mod` 2 == 0 = [(a, b) | a <- takeWhile (<n) primes, b <- takeWhile (<n) primes, n == a + b]
| otherwise = []
但是,如果我没记错的话,这与实际的哥德巴赫猜想无关。