2016-03-09 51 views
0

我有一個任務需要使用命令行參數實現一個循環版本的FizzBu​​zz,將2個除數與一個數字進行比較,如果upBound可以被div1整除,則打印Fizz,如果upBound可以被div2整除, upBound,如果它不能被二者整除。我已經構造函數和我能夠使用獨立的主要功能,但爲了編譯,我顯然需要的主要功能,這點我已經試過落實以下在Haskell中調用打印功能

module Main(main) where 
import System.Environment 

fizzBuzz div1 div2 upBound = do if (upBound - 1) > 1 
           then fizzBuzz div1 div2 (upBound - 1) 
           else print ""; 
           if mod (upBound - 1) div1 > 0 && mod (upBound - 1) div2 > 0 
           then print (upBound - 1) 
           else 
            print ((if mod (upBound - 1) div1 == 0 then "Fizz" else []) ++ (if mod (upBound - 1) div2 == 0 then "Buzz" else [])) 

main = do 
    [div1,div2,upBound] <- getArgs 
    fizzBuzz div1 div2 upBound 

我已經沖刷每教程和幫助網站我可以找到,我只是不太瞭解Haskell,它的語法來確定究竟是什麼錯誤。目前,我試圖編譯時得到以下錯誤:

「fizzbuzz.hs:14:9:沒有實例從使用的‘fizzBu​​zz’產生(積分字符串)」爲例

我的預期輸出是一樣的東西

fizzbuzz 2 4 6

1 
Fizz 
3 
FizzBuzz 
5 
Fizz 

不幸的是,我似乎無法找到正確的幫助資源來找出如何解決這個問題,並希望有人能指出我正確的方向。

預先感謝您。

+4

你的'fizzBu​​zz'函數本質上需要三個整數參數 - 但'getArgs'給你一個字符串列表。你必須從字符串轉換爲整數 - 快速和骯髒的方式將是'fizzBu​​zz(讀取a)(讀取b)(讀取c)'。 – user2407038

+0

我對你的評論@Mephy感到困惑。不是所有'if'表達式在'then'和'else'中都有相同的類型,即'IO()'?哪個表達式不滿足這個約束? – amalloy

回答

1

當您遇到這樣的,這是最好看所涉及的類型:

  • 的fizzBu​​zz功能需要3個數字,並返回一個IO()動作

  • 的getArgs功能型getArgs :: IO [String]

這意味着,在maindiv1具有類型String; div2有類型String;和upBound有類型String。您直接將它們傳遞給fizzBuzz,但回想起它期望的數值參數!這就是爲什麼你會得到關於(Integral String)的錯誤;因爲數字參數可以是類型類別中的任何一個,所以它告訴您無法找到String是其所期望的數字類成員的證據。

您需要以某種方式將命令行中的字符串解釋爲數字。最簡單的方法是read方法,其類型爲Read a => String -> a。這意味着如果您想要從字符串解析的類型是「可讀」類類型的成員,則它可以採用String併爲您提供該類型的實例。

+0

優秀的建議,做user2407038的建議工作,這是一個很好的解釋! – Xiphoen