2015-11-14 61 views
1

我寫這樣的代碼越來越<<loop>>消息運行的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錯誤。

+0

那麼,您使用了什麼輸入參數?這是分配給xs的東西。請粘貼整個運行命令。 – EkcenierK

+0

@KLibby例如'$ ./run my_string any_argument'這正是我所提到的 – PepeHands

+0

[Haskell綁定變量時的無限循環]的可能重複(http://stackoverflow.com/questions/28553559/infinite-loop-in -haskell-when-binding-variables) – Zeta

回答

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() 

和您的代碼應該按預期工作;)

+0

是的,你是對的。愚蠢的我。非常感謝! – PepeHands

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文件或其他任何構建系統中啓用警告)

相關問題