关于偶数和奇数的Haskell函数

时间:2013-09-22 17:17:28

标签: function haskell numbers

我是Haskell的新手,几天前开始学习,我对我正在尝试的功能有疑问。

我想创建一个函数来验证 x 是否是 n 的因子(例如:375具有以下因素:1,3,5,15,25, 75,125和375),然后删除1然后删除数字本身,最后验证该列表中奇数的数量是否等于偶数的数量!

我想过制作这样的函数来计算第一部分:

factor n = [x | x <- [1..n], n `mod`x == 0]

但如果我把它放在提示符上,它会说Not in scope 'n'。想法是输入一个像375这样的数字,以便计算清单。我做错了什么?我已经在书中看到了这样的提示功能。

然后采取我所说的元素,我正在考虑做尾巴,然后初始化到列表中。你认为这是个好主意吗?

最后我想到制作一个if语句来验证最后一部分。例如,在Java中,我们会做类似的事情:

(x % 2 == 0)? even++ : odd++; // (I'm a beginner to Java as well)

然后如果偶数=奇数则会说所有条件都经过验证(我们有一定数量的偶数等于奇数)

但是在Haskell中,由于变量是不可变的,我该如何处理++事物呢?

感谢您提供的任何帮助:)

5 个答案:

答案 0 :(得分:4)

这个小功能完成了你想要实现的一切:

f n = length evenFactors == length oddFactors
  where evenFactors = [x | x <- [2, 4..(n-1)], n `mod` x == 0]
        oddFactors  = [x | x <- [3, 5..(n-1)], n `mod` x == 0]

答案 1 :(得分:3)

如果“命令行”是ghci,那么你需要

let factor n = [x | x <- [2..(n-1)], n `mod` x == 0]

在这种特殊情况下,您不需要将[1..n]范围仅限于1和n - 范围从2到(n-1)。

你可以简单地使用分区来使用布尔谓词来分割除数列表:

import Data.List
partition odd $ factor 10

为了学习如何编写像partition这样的函数,请研究递归。

例如:

partition p = foldr f ([],[]) where
  f x ~(ys,ns) | p x = (x:ys,ns)
  f x ~(ys,ns) = (ys, x:ns)

(这里我们需要使用“〜”懒惰模式匹配元组,以确保在构造右边的元组之前不评估模式)。

简单计数可以更简单地实现:

let y = factor 375
(length $ filter odd y) == (length y - (length $ filter odd y))

答案 2 :(得分:2)

创建一个文件source.hs,然后从ghci命令行调用:l source加载source.hs中定义的函数。

要解决您的问题,这可能是您的步骤后的解决方案:

-- computers the factors of n, gets the tail (strips 1)
-- the filter functions removes n from the list
factor n = filter (/= n) (tail [x | x <- [1..n], n `mod` x == 0])

-- checks if the number of odd and even factors is equal
oe n = let factors = factor n in 
           length (filter odd factors) == length (filter even factors)

致电oe 10返回Trueoe 15返回False

答案 3 :(得分:1)

(x % 2 == 0)? even++ : odd++;

我们Data.List partition :: (a -> Bool) -> [a] -> ([a], [a])函数

所以我们可以划分赔率

> let (odds,evens) = partition odd [1..]

> take 10 odds
 [1,3,5,7,9,11,13,15,17,19]
> take 10 evens
 [2,4,6,8,10,12,14,16,18,20]

答案 4 :(得分:0)

以下是使用理解的factor尝试的最小修复:

factor nn = [x | n <- [1..nn], x <- [1..n], n `mod`x == 0]