得到&lt; <loop>&gt;运行haskell程序时的消息

时间:2015-11-14 10:33:59

标签: haskell

我写了这样的代码

import System.Environment
import Control.Exception
import Data.List

f :: String -> [String] -> IO ()
f str []       =
    putStrLn "String 2"
f str (x : xs) =
    putStrLn "String 1"

main :: IO ()
main = do
    xs <- getArgs
    let str = head xs
    let xs = tail xs
    f str xs
    return ()

但是当我编译并尝试运行时,我总是只回答<<loop>>

ghc run.hs
./run some_string some_over_arguments
run: <<loop>>

这段代码有什么问题?我试图怂恿<<loop>>,却一无所获。如果我转到f而不是str xsstr [some_hardcoded_list]此代码正常,那么我认为xs有问题。

2 个答案:

答案 0 :(得分:5)

您会看到您声明的部分

let xs = tail xs

这表示你希望xs成为一个尾巴的列表,这会导致一个infinte循环(ghc似乎注意到了;))(看作每个定义)常量列表repeat c就足够了 - 技术上当然你只是得到一个简单的无限循环)

所以只需将其更改为

main :: IO ()
main = do
    xs <- getArgs
    let str = head xs
    let xs' = tail xs
    f str xs'
    return ()

并且您的代码应该按预期工作;)

答案 1 :(得分:3)

其他人已经回答了。我只想补充说,启用警告将指出现有绑定的重新定义。这也涵盖了这种不需要的递归:

> :set -Wall
> xs <- return [1..10::Int]
> let xs = tail xs

<interactive>:11:5: Warning:
    This binding for ‘xs’ shadows the existing binding
      defined at <interactive>:10:1

现在,人们可以想到“但在这种情况下,我真的打算隐藏前一个绑定”,并且完全正确。尽管如此,偶然重命名新绑定可以避免这个问题。

在源文件的顶部添加{-# OPTIONS -Wall #-}的另一个原因。 (或在.cabal文件或其他任何构建系统中启用警告)