我正在查看过去的试卷,但不知道如何转换Int
为[Int]
. 例如,其中一个问题要求我们生成一个整数的所有因子的列表,不包括数字本身和 1。
strictFactors Int -> [Int]
strictFactors x = ???
我不是要求任何人为我做这个问题!我只想知道如何将整数输入转换为整数输出列表。谢谢!
也许看看一些类似的代码是最容易的。按照要求,我不会给你答案,但你应该能够使用这些想法来做你想做的事。
在这里,我们将使用1
和之间的所有数字对x
来测试我们是否可以将x
其作为两个平方数的和:
sumOfSquares :: Int -> [Int]
sumOfSquares x = [ (a,b) | a <- [1..x], b <- [a..x], a^2 + b^2 == x]
你这样称呼它:
ghci> asSumOfSquares 50
[(1,7),(5,5)]
因为 50 = 1^2+7^2 而且 50 = 5^2 + 5^2。
您可以认为sumOfSquares
首先从 和 之间的数字列表中获取一个,然后a
在该 和 之间获取另一个。然后检查. 如果这是真的,它会添加到结果列表中。[1..x]
1
x
x
a^2 + b^2 == x
(a,b)
这次让我们生成一些单个数字,然后检查它们是否是另一个数字的倍数。这将计算最小公倍数 (lcm)。例如,15 和 12 的最小公倍数是 60,因为它是 15 和 12 乘法表中的第一个数字。
此功能不是您想要的类型,但它使用了您想要的所有技术。
lcm :: Int -> Int -> Int
lcm x y = head [x*a | a <- [1..], (x*a) `mod` y == 0]
你可以这样称呼它:
ghci> lcm 12 15
60
这次数字列表[1..]
(原则上)是无限的;干得好,我们只是选择了第一个head
!
(x*a) `mod` y == 0
检查该数字是否是(给出除法后的余数x*a
) 的倍数。这是您应该使用的关键思想。y
mod
用于a <- [1..end]
生成数字,用 True/False 表达式(即 a Bool
)测试它们,也许使用mod
函数。
我是 Haskell 的新手,但可以想到无数种方法将 Int“转换”为包含相同 Int 的列表:
import Control.Applicative (pure)
sane_lst :: Int -> [Int]
sane_lst x = [x]
lst :: Int -> [Int]
lst x = take 1 $ repeat x
lst' :: Int -> [Int]
lst' = replicate 1
lst'' :: Int -> [Int]
lst'' = return
lst''' :: Int -> [Int]
lst''' = pure
lst'''' :: Int -> [Int]
lst'''' x = enumFromTo x x
我想这里的重点是您不要“转换”为列表,而是“构建”您需要的列表。针对您提出的问题,直截了当的策略是根据您的参数找到可以为您提供合适的起始列表的内容,然后根据需要进行过滤、折叠或理解。
例如,当我说:
lst x = take 1 $ repeat x
我首先构造一个无限列表,重复我传入的值,然后从中取出一个仅包含第一个元素的列表。因此,如果您考虑需要从哪种列表开始以找到问题的解决方案,那么您将成功。
如果您唯一的目标是在类型之间进行转换(目前),那么strictFactors x = [x]
这是最规范的答案。此函数也称为pure
因为[]
是所谓的 anApplicative
并且return
因为[]
是已知的 a Monad
。