简体   繁体   中英

Infinite List of Products in Haskell

The problem I am trying to solve using Haskell is defined as this:

Write a function that takes a list of numbers in increasing order and
returns a list of all Integers (in increasing order) that can be made
by multiplying only the numbers in the input list. Note that this is
an infinite list, eg., for the input list 2, 3, 5, the output list will be
2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, ...

In Haskell I have the following code established:

prodList s = [f| f <- [(head s)..], isProd f s]

isProd f [] = False
isProd f s = ((mod (f (head s))) == 0) || (isProd f (tail s))

In the prompt I get this error when trying to compile:

Occurs check: cannot construct the infinite type: a1 = a1 -> a0
Expected type: [a1]
  Actual type: [a1 -> a0]
In second argument of 'isProd', namely 's'
In the expression: isProd f s
In the stmt of a list comprehension: isProd f s

So basically I have a very shallow depth into types so if someone could explain the error to me and a possible fix.

When you get type errors, always annotate your functions with explicit types. You'll get much nicer error messages. In this case if we look at the type of isProd we get

isProd
  :: (Eq (a -> a), Integral a, Num (a -> a)) =>
     (a1 -> a) -> [a1] -> Bool

clearly this is not right! In this case you're applying f to head s rather than feeding them both into mod . I believe you wanted

isProd f s = mod f (head s) == 0 || isProd f (tail s)

This fixes your type error.

However you still have a logic error since prodList [2, 3, 5] will include 21 since 3 * 7 == 21 , but this isn't what you want. The problem is that you're too permissive as for what isProd accepts. It should not check that f is divisible by some number in the list, but that there are two numbers in s that when multiplied yield f . Since this is homework I'll leave this to you to figure out.

The problem is in the expression:

mod (f (head s)

Which treats f as a function. The correct version is:

isProd f s = ((mod f (head s)) == 0) || (isProd f (tail s))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM