Haskell中的无限产品列表

red*_*ing 1 haskell types list

我试图用Haskell解决的问题定义如下:

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 infinite 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, ...
Run Code Online (Sandbox Code Playgroud)

在Haskell中,我建立了以下代码:

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

isProd f [] = False
isProd f s = ((mod (f (head s))) == 0) || (isProd f (tail s))
Run Code Online (Sandbox Code Playgroud)

在提示符中,我在尝试编译时遇到此错误:

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
Run Code Online (Sandbox Code Playgroud)

所以基本上我对类型有一个非常浅的深度,所以如果有人可以向我解释错误和可能的修复.

Dan*_*zer 5

当您遇到类型错误时,始终使用显式类型注释您的函数.您将获得更好的错误消息.在这种情况下,如果我们看看isProd我们得到的类型

isProd
  :: (Eq (a -> a), Integral a, Num (a -> a)) =>
     (a1 -> a) -> [a1] -> Bool
Run Code Online (Sandbox Code Playgroud)

显然这不对!在这种情况下,你申请fhead s,而不是他们俩送入mod.我相信你想要的

isProd f s = mod f (head s) == 0 || isProd f (tail s)
Run Code Online (Sandbox Code Playgroud)

这可以修复您的类型错误.

但是你仍然有一个逻辑错误,因为从那以后prodList [2, 3, 5]会包含21 3 * 7 == 21,但这不是你想要的.问题在于你对isProd接受的东西过于宽容.它不应该检查f是否可以被列表中的某个数字整除,但是s当乘以yield时,有两个数字f.由于这是作业,我会留给你弄清楚.