我对Haskell很陌生,我认为为了掌握编写Haskell程序的窍门,我可能会解决一些ProjectEuler问题。
所以我继续进行,实现了项目Euler的第4个问题。
问题陈述:
回文数的两种读法相同。由两个两位数的乘积产生的最大回文是9009=91×99。
找出两个3位数的乘积所产生的最大回文。
但我的解决方案似乎有问题。
这里是:
| 12
 3
 4
 
 | projectEuler4 :: (Ord  a,Num  a) =>  a 
 
projectEuler4 = max  palindromeList
  where  palindromeList = [reverse( x* y)| x<-[1 ..999] ,y <- [1 ..999]] | 
GHCI给出了以下错误:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 
 | ProjectEuler4.hs:2:17: 
Could not  deduce ( a ~ ([[ a0]] -> [[ a0]])) 
from the context (Ord  a, Num  a) 
  bound by the type  signature for 
             projectEuler4 :: (Ord  a, Num  a) =>  a 
  at ProjectEuler4.hs:1:18-35 
  `a' is a rigid type  variable bound by 
      the type  signature for projectEuler4 :: (Ord  a, Num  a) =>  a 
      at ProjectEuler4.hs:1:18 
In the return type of  a call of  `max ' 
Probable cause:  `max ' is applied to too few arguments 
In the expression: max  palindromeList 
In an equation for `projectEuler4': 
    projectEuler4
      = max  palindromeList
      where 
          palindromeList
            = [reverse ( x *  y) |  x <- [1  .. 1000] , y <- [1  .. 1000]] | 
我不知道这意味着什么,并且因为找不到错误的原因而感到沮丧。如有任何帮助,我们将不胜感激。谢谢。
所以在阅读了一些答案和评论之后,我做了这样的事:
| 12
 3
 4
 5
 6
 7
 8
 
 | projectEuler4 :: (Ord  a,Num  a) =>  a  
projectEuler4 = max ' palindromeList
    where  palindromeList = [reverse(show( x* y))| x<-[1 ..999] ,y <- [1 ..999]]
max ' :: (Ord  a) => [ a] ->  a
max ' [] = error"Empty List"
max ' [ p] =  p
max ' ( p: ps) = max  p (max ' ps) | 
还是不行。
好啊。。
按照@bheklillr的建议,我更改了我的程序:
现在我应该用什么来代替逗号?我很困惑。
		
		
- 这可能与你写max(palindromeList)的方式有关。试试max palindromList,不带括号。Haskell不使用C风格的调用约定。
- @Eric这两个表达式是等效的。parens用于分组,不影响(((5))) + 4的书写。
- 那么类型类有什么问题吗?
- 你需要一个haskell教程来开始。max使用的是两个数字,而不是一个列表(尽管也可以使用列表)。您可以使用ghci :t max或使用hoogle查找类似的信息。
- @我认为在函数和参数之间没有一个空格会导致一个问题,但我看到它没有。今天我学到了…
- @bhavyasrivastava,filter函数就是我们所说的"高阶函数"。它以一个函数作为参数,并以特定的方式使用该函数。作为第一个参数的函数必须具有a -> Bool类型,其中第二个参数是[a]类型的列表。它将谓词应用于列表中的每个元素,因此像filter even [1..10]这样的东西会返回[2, 4, 6, 8, 10](fyi even :: Integer -> Bool)。另外,在maximum和filter之间需要一个$。
- 我得到了我的答案……谢谢……我实际上是通过修改你给出的代码来解决的。
 
	 
| 12
 
 | Prelude> : t max
max :: (Ord  a) =>  a ->  a ->  a | 
这就是max的类型。当您在a类型的某个参数上调用它时,会得到a -> a类型的结果—一个函数。这是因为通常使用两个值调用max;部分应用会导致函数在计算结果之前仍等待第二个参数,这是两个值中最大的一个。
误差表明,haskell将palindromeList的类型推导为[[a0]],结果的类型为[[a0]] -> [[a0]]。你给它的原因是埃多克斯1〔11〕和哈斯克尔不能匹配这两个。
您打算使用maximum,它处理一个列表并在其中找到最大的价值:
palindromeList的定义也是错误的。对于初学者,[1..999]中从1到99的数字不是三位数。然后你需要测试它们。当然,reverse (x*y)是错误的:reverse :: [a] -> [a]但是两个数相乘的结果是一个数,但是-即使你修正了它,这仍然不是一个测试。
测试类似于show (x*y) == reverse (show (x*y))。
第一个大错误是你打电话来
由于x * y是一个数字,而reverse只在列表上工作,所以无法编译。您可以使用show将数字转换为String(即列表):
但是,反转字符串并不是您真正想要做的,您需要过滤查找所有回文,因此需要用谓词过滤您的EDOCX1[22]列表。相反,你可以写
| 1
 | palindromeList = [ z |  x <- [1 ..999] , y <- [1 ..999] , let  z =  x *  y, if show  z == reverse (show  z)] | 
但由于这是从屏幕的侧面进行的,所以我建议将其分成更小的功能
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 
 | -- Generates all products
products :: [Integer] -> [Integer] -> [Integer] 
products ns ms = [ x *  y |  x <-  ns, y <-  ms]
-- Checks if a number is a palindrome 
isPalindrome :: Integer -> Bool 
isPalindrome n = let  s = show  n in  s == reverse  s
-- Generates problem-specific palindromes 
palindromes :: [Integer] 
palindromes = ??? -- Implementation here.  Hint: filter | 
下一个大问题是因为您使用的是max函数,它具有
但是我们真的想找到一个列表的最大值,所以我们转向maximum,它的类型是
所以你可以把你的计划定为
最后一个想法是:问题是你需要找到最大的回文数,它是2个三位数的倍数,但是你要查找的范围是[1..999],它包括1和2位数。你怎么能不检查那些呢?很方便,它可以使程序更快。
 
你需要找到两个三位数的回文数的最大乘积。程序将生成回文数列表,并找到该列表的最大值。第一步是生成产品的术语,称之为x和y。这是使用生成器x <- [100..999]和y <- [x..999]完成的。注意,如果我们考虑的是x的一个特殊值,我们只需要考虑y大于或等于x的值;如果不是,我们重复我们自己。接下来,我们需要确定xy是否是回文。最简单的方法是将xy转换成字符串,称之为s,然后检查reverse s == s是否有效。为此,请使用show :: Show a = a -> String。生成的列表的最大值可以通过函数maximum :: Ord a => [a] -> a找到。
| 12
 3
 
 | euler4 :: Integral  a =>  a 
euler4 = maximum [  x *  y |  x <- [100 ..999] , y <- [ x..999] , palindromic ( x *  y) ]
  where  palindromic n = show  n == reverse (show  n) | 
您的代码有几个问题。首先,projectEuler4应该是一个整数值,所有整数值都已经是Ord和Num的实例。正确的约束是Integral a => a。这样可以选择Int或Integer。其次,max :: Ord a => a -> a -> a给出了Ord类型类的两个成员的最大值,而不是列表第三个元素的最大值,reverse :: [a] -> [a]对列表进行操作,而不是数值;在应用于reverse之前,需要将x * y转换为String。第四,y <- [999]是指y是从单体清单生成的,单体清单只包含999,而不是从x到999或从100到999的数字清单。
haskell.org的haskell教程对列表理解有很好的概述。我还将查找haskell类型系统的概述,并学习使用交互式GHC环境,尤其是命令:t(如果您不确定函数的类型,并且不熟悉标准库)。
您正试图用以下值反转一个数字:
reverse只适用于列表。幸运的是,String是一个列表,而show是创建String值表示的规范方法。
因此,尝试以下方法:
		
		
- True,but not given the reason for the error message。威尔仍(相似),which is when this固定。):
- 是的..the didnt Change messages。