Question

I'm looking through a past exam paper and don't understand how to convert Int to [Int]. For example, one of the questions asks us to produce a list of all the factors of a whole number excluding both the number itself and 1.

strictFactors Int -> [Int]
strictFactors x = ???

I'm not asking for anyone to do this question for me! I just want to know how I'd convert an integer input to a list of integer output. Thanks!

Était-ce utile?

La solution

Perhaps it would be easiest to have a look at some similar code. As requested, I won't give you the answer, but you should be able to use these ideas to do what you want.

Brute force

Here we're just going to use all the pairs of numbers between 1 and x to test if we can make x as the sum of two square numbers:

sumOfSquares :: Int -> [Int]
sumOfSquares x = [ (a,b) | a <- [1..x], b <- [a..x], a^2 + b^2 == x]

You call this like this:

ghci> asSumOfSquares 50
[(1,7),(5,5)]

because 50 = 1^2+7^2 and also 50 = 5^2 + 5^2.

You can think of sumOfSquares as working by first taking an a from the list [1..x] of numbers between 1 and x and then another between that and x. It then checks a^2 + b^2 == x. If that's True, it adds (a,b) to the resulting list.

Generate and check

This time let's generate some single numbers then check whether they're a multiple of another. This will calculate the least common multiple (lcm). For example, the least common multiple of 15 and 12 is 60, because it's the first number that's in both the 15 and 12 times tables.

This function isn't of the type you want but it uses all the techniques you want.

lcm :: Int -> Int -> Int
lcm x y = head [x*a | a <- [1..], (x*a) `mod` y == 0]

You can call that like this:

ghci> lcm 12 15
60

This time the list of numbers [1..] is (in principle) infinite; good job we're just picking the first one with head!

(x*a) `mod` y == 0 does the checking to see whether the number x*a is a multiple of y (mod gives the remainder after division). That's a key idea you should use.

Summary

Use a <- [1..end] to generate numbers, test them with a True/False expression (i.e. a Bool), perhaps using the mod function.

Autres conseils

I'm quite new at Haskell but can think of a myriad ways of "converting" an Int to a list containing that same 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 

I guess the point here is that you don't "convert" to a list, you rather "construct" the list you need. The staightforward strategy for the kind of question you posed is to find something that will give you a suitable starting list to work with based on your parameter, then filter, fold or comprehend as needed.

For example when I say:

lst x = take 1 $ repeat x 

I'm first constructing an infinite list repeating the value I passed in, and then taking from it a list containing just the first element. So if you think about what kind of list you need to start with to find the solution to your problem you'll be halfway there.

If your only goal is to convert between the types (for now) then strictFactors x = [x] is the most canonical answer. This function is also called pure since [] is what's known as an Applicative and return since [] is known as a Monad.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top