为什么我的程序中出现了解析器错误?

时间:2015-11-12 20:42:24

标签: haskell

我为problem 25 on Euler编写了一个Haskell程序。我认为我的程序应该运行并返回正确的答案,但它没有:

-- Problem25.hs
module Main where

fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)

length1 :: Integer -> Int
length1 = length . show

main :: IO ()
main = do
  list1 <- [1..]
  list2 <- zip3 list1 list1 list1
  list3 <- map funct list2
    where funct u v w = (u, fib u, length1 (fib u))
  putStrLn "number : "                                                 -- line 17
  putStrLn $ show . head . ( dropWhile ( \(u,v,w)-> w < 1000  ) list3)  

但是,我收到以下错误:

$ ghc Problem25.hs
[1 of 1] Compiling Main             ( Problem25.hs, Problem25.o )

Problem25.hs:17:3: parse error on input `putStrLn'

为什么我会收到解析器错误?我在do区块,所以putStrLn "number : "应该没问题,对吗?

1 个答案:

答案 0 :(得分:2)

这是一个删除了所有语法错误的版本:

module Main where

fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)

length1 :: Integer -> Int
length1 = length . show

main :: IO()
main = do
  putStrLn "hello"

  let liste = [1..]
  let liste2 = zip3 liste liste liste
  let liste3 = map funct liste2
  putStrLn "number : "
  putStrLn $ show . head $ (dropWhile ( \(_,_,w)-> w < 1000  ) liste3)  
    where funct (u,_,_) = (u,fib u,length1 (fib u))

你可以看到有很多:

  • where位于do块的中间 - &gt;这必须走到尽头
  • <-而非let ... = ... - 请记住:<-从计算中提取值 - 在这种情况下,从a获取IO a .
  • 上一个putStrLn中有一个dropWhile到多个(zip3的最后一个部分是值而不是函数)
  • 您必须使用3元组参数而不是咖喱版本的几个地方,因为您选择使用fib(返回元组)

还要注意,虽然这个编译并运行它很可能不是一个好的(甚至可行的)解决方案 - 我只是删除你的语法问题 - 为了得到一个好的解决方案,你应该首先处理你的{{1 (表现不佳 - 有更好的计算方法 - 提示:在你的搜索引擎上搜索Haskell + Fib)

以下是一些评论:

  • 你不需要zip3部分相同列表的3倍 - 你可以让你的funct做这项工作(顺便说一下:你已经做了 - 你忽略第二和第三参数)
  • 为什么你dropWhile然后抬头? (filter和头部似乎更自然IMO)
  • 当然你也应该重新考虑funct部分(注意你从不需要元组中的中间项?)

祝其他运动好运;)

有点清理

我清理了你的解决方案:

fib :: Int -> Integer
fib 1 = 1
fib 2 = 1
fib n = fib (n-1) + fib (n-2)

length1 :: Integer -> Int
length1 = length . show

solve :: Int
solve = head . filter ((>= 1000) . length1 . fib) $ [1..]

main :: IO()
main = do
  putStrLn "number : "
  print solve

仍然没有更好的表现(这是你的挑战),但至少它适用于3数字而不是1000(尽管即使10也会这需要相当长的时间......)

<强>享受

无法帮助

我必须尝试它,确实如果你定义这样的序列:

import Data.List (unfoldr)

fibs :: [Integer]
fibs = unfoldr fib (1,1)
  where fib (n,m) = Just (n,(m,n+m))

(这与你在循环中通常所做的相近)

你会很快得到答案(4782

当然你必须考虑如何获取索引(提示:现在zip可能是一个好主意)