2011-02-25 38 views
0

所以我剛開始學習Haskell,我試圖用這個if語句:我的if有什麼問題?

[if (((mod x 3) == 0) && ((mod x 5) == 0)) then "Fizzbuzz" else x | x <- [1..50]] 

,但是當我在ghci中編譯,我得到以下錯誤:

No instance for (Integral [Char]) 
     arising from a use of `mod' at baby.hs:22:19-25 
    Possible fix: add an instance declaration for (Integral [Char]) 
    In the first argument of `(==)', namely `(mod x 3)' 
    In the first argument of `(&&)', namely `((mod x 3) == 0)' 
    In the expression: (((mod x 3) == 0) && ((mod x 5) == 0)) 
Failed, modules loaded: none. 

好了,所以我我們發現x被推斷爲一個字符串,因爲if返回一個顯式字符串,因此這個整個函數將不起作用。那麼我怎麼才能真正解決這個問題呢? (我知道我的問題是愚蠢的,但我不習慣用功能範例或靜態鍵入類型推理)。

+5

什麼是'x'?它似乎是一個'字符串'。 – kennytm 2011-02-25 06:24:24

+0

@KennyTM是正確的。沒有看到更多的代碼,很難幫助你。如果'x'是一個Int,這個代碼就沒問題。 – luqui 2011-02-25 06:36:50

+1

請縮小爲可上傳大小的代碼片段,幷包含錯誤消息(但肯定的,從它的聲音KennyTM在正確的軌道上)。 – 2011-02-25 06:46:58

回答

-1
main = mapM_ (putStrLn . fb) [1..100] 

fb :: Int -> String 
fb x | [3,5] `divides` x = "fizzbuzz" 
    | [5] `divides` x = "buzz" 
    | [3] `divides` x = "fizz" 
    | otherwise   = show x 

divides :: [Int] -> Int -> Bool 
xs `divides` y = y `mod` product xs == 0 
-3

從外觀上來看,你正在試圖解決歐拉計劃的問題1.嘗試使用「MOD」功能在其綴形式,即是這樣的:

if ((x `mod` 3 == 0) && (x `mod` 5 == 0)) then blah blah 

認爲這將迫使編譯器認爲x將會是一個Int。否則,你將不得不向我們提供更多信息,比如KennyTM,luqui和TomMD(可能錯誤在其他地方)。

+8

我不同意。 '(mod x 3)'與'(x \'mod \'3)'完全相同。中綴和前綴形式之間唯一可能的區別是運算符優先級,但在這裏並不重要。 – Rotsor 2011-02-25 07:21:46

+0

確實,它甚至相當於'((\'mod \'3)x)' – barsoap 2011-02-25 10:47:00

+1

不,項目歐拉問題1涉及那些可以被三或五,而不是三和五整除的數字。事實上,OP似乎正試圖解決FizzBu​​zz問題。 – jason 2011-02-25 14:32:25

4

問題不在於這部分代碼。錯誤消息是關於mod的類型是mod :: (Integral a) => a -> a -> a,但x據說是類型[Char]。

我猜測這裏x的類型是在這裏推斷的(因爲類型應該是int)。爲此,爲了調試,我建議這個問題你申報你的函數類型,就像這樣:

f :: Int -> ... 
f x ... = if (((mod x 3) == 0) && ((mod x 5) == 0))... 

如果仍然有問題,張貼代碼的其餘部分。

7

'then'和'else'分支必須具有相同的類型。 "Fizzbuzz"是一個字符串,因爲x是一個Int。如果您打算打印結果,則只需將show x用於您的else分支。

也許這可以很好地添加到Haskell的common misunderstandings的if/then/else部分。出於同樣的原因,else分支必須存在,它也必須具有與then相同的類型。

2

您真正需要做的就是添加顯示爲了將您的Int轉換爲字符串。

[if mod x 3 == 0 && mod x 5 == 0 then "Fizzbuzz" else show x | x <- [1..50]] 

至極又可以寫爲:

map (\x -> if mod x 15 == 0 then "Fizzbuzz" else show x) [1..50]