简体   繁体   English

Haskell中无限的产品列表

[英]Infinite List of Products in Haskell

The problem I am trying to solve using Haskell is defined as this: 我试图使用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 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: 在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))

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的类型, isProd得到

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 . 在这种情况下,您将f应用于head s而不是将它们都输入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. 但是,由于prodList [2, 3, 5]由于3 * 7 == 21 ,所以prodList [2, 3, 5]将包含21 prodList [2, 3, 5]因此您仍然会遇到逻辑错误,但这不是您想要的。 The problem is that you're too permissive as for what isProd accepts. 问题是您对于isProd接受的内容过于宽容。 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 . 它不应该检查f是否可以被列表中的某个数整除,而是应检查s中有两个数字乘以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. 将f作为函数。 The correct version is: 正确的版本是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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