How to return a list from a function?

Viewed 77

I have this function in Haskell to get perfect numbers. I want to return a list of perfect numbers.

perfect :: Int -> []
perfect digit  = [presentNum | presentNum <- [1..digit], isPerfect presentNum]

isPerfect :: Integer -> Bool   --function declaration 
isPerfect n =  n == sum [i | i <- [1..n-1], n `mod` i == 0]

but I am met with the error

  • Expecting one more argument to []' Expected a type, but[]' has kind `* -> *'
  • In the type signature: perfect :: Int -> []

How do I properly return a list?

2 Answers

You have to specify the type of the list elements:

perfect :: Int -> [Int]
                -- ^^^ --

There is no type of "lists" [], but only types such as "list of integers" [Int], "list of strings" [String] and so on.

Technically, Haskell does allow [] as a type constructor of kind * -> * (that's what the error reports), making [] not a type but something that takes a type like Int and returns a type [Int]. So, roughly, [] is a function from types to types, not a type.

The type signature is wrong. If you return a list of Ints, then it should be [Int] (or [] Int):

perfect :: Int -> [Int]
perfect digit = [presentNum | presentNum <- [1..digit], isPerfect presentNum]

Here it might however be easier to work with filter :: (a -> Bool) -> [a] -> [a]:

perfect :: Int -> [Int]
perfect digit = filter isPerfect [1..digit]

We can work with enumFromTo :: Enum a => a -> a -> [a] to make a point-free implementation"

perfect :: Int -> [Int]
perfect = filter isPerfect . enumFromTo 1
Related