我写了这样的代码
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 xs
但str [some_hardcoded_list]
此代码正常,那么我认为xs
有问题。
答案 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文件或其他任何构建系统中启用警告)