Haskell中的无限产品列表

时间:2014-03-10 21:55:46

标签: list haskell types

我试图用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, ...

在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))

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

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

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

2 个答案:

答案 0 :(得分:5)

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

isProd
  :: (Eq (a -> a), Integral a, Num (a -> a)) =>
     (a1 -> a) -> [a1] -> Bool
显然这不对!在这种情况下,您将f应用于head s,而不是将它们都提供给mod。我相信你想要

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

这可以解决您的类型错误。

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

答案 1 :(得分:1)

问题在于表达式:

mod (f (head s)

将f视为一种功能。正确的版本是:

isProd f s = ((mod f (head s)) == 0) || (isProd f (tail s))
相关问题