2013-10-31 81 views
0

在Haskell中,我嘗試這樣做:功能重複N次錯誤

multi::(Num n)=>n->((a->a)->(a->a)) 
(multi 0) f x=x 
(multi n) f x=(multi n-1) f (f x) 

希望能得到那會重複另一個函數的次數的函數。 在ghci中,我得到這個:

[1 of 1] Compiling Main    (pad.hs, interpreted) 

pad.hs:2:8: 
    Could not deduce (Eq n) arising from the literal `0' 
    from the context (Num n) 
     bound by the type signature for 
       multi :: Num n => n -> (a -> a) -> a -> a 
     at pad.hs:1:8-35 
    Possible fix: 
     add (Eq n) to the context of 
     the type signature for multi :: Num n => n -> (a -> a) -> a -> a 
    In the pattern: 0 
    In an equation for `multi': multi 0 f x = x 

pad.hs:3:23: 
    Could not deduce (Num ((a -> a) -> a -> a)) 
     arising from a use of `-' 
    from the context (Num n) 
     bound by the type signature for 
       multi :: Num n => n -> (a -> a) -> a -> a 
     at pad.hs:1:8-35 
    Possible fix: 
     add an instance declaration for (Num ((a -> a) -> a -> a)) 
    In the expression: multi n - 1 
    In the expression: (multi n - 1) f (f x) 
    In an equation for `multi': multi n f x = (multi n - 1) f (f x) 
Failed, modules loaded: none. 

我哈斯克爾一個新手。我該怎麼辦?

回答

2

你幾乎做到了。最小的修復方法是在n - 1附近添加括號並刪除簽名:

(multi 0) f x=x 
(multi n) f x=(multi (n-1)) f (f x) 
+0

非常好,簡潔。其他的問題都放在他們的代碼中,但你是唯一明確表示要做'(n-1)'而不是'n-1'的人。 – PyRulez

4

夫婦的事情。你不能檢查Num的平等。您可能正在尋找一個Int。其次,你不需要圍繞多重的偏見,這是爭論。和其他一些格式。

multi :: Int -> (a -> a) -> a -> a 
multi 0 f x = x 
multi n f x = multi (n-1) f (f x) 

你可以使這種類型的簽名更通用,但我們會堅持。但是你可以用更高階的函數來寫這個東西。

multi :: Int -> (a -> a) -> a -> a 
multi n f a = foldl (\v _ -> f v) a [1..n] 
+0

在你的第二個實現中,會不會更懶惰? – cheecheeo

2

我可以讓你的程序,使得它編譯最小的變化是:

multi::(Eq n, Num n)=>n->((a->a)->(a->a)) 
(multi 0) f x=x 
(multi n) f x=(multi (n-1)) f (f x) 

Num型類不需要成員已經是Eq成員,所以我們必須指定也是如此。此外,我們想通過n-1作爲參數傳遞給multi

這個問題在哈斯克爾土地通常用做和iterate!!

1

有幾件事情錯在這裏。

Num n並不意味着Eq n,這意味着Num類型類定義中沒有Eq n => Num n約束。爲了在0上匹配模式,您需要將n類型作爲Eq的實例。我只想明確地將其更改爲Int,沒有理由在這一塊額外的代碼普遍性。

接下來,(multi n-1)適用multin然後減去1 .B我也清理了代碼,並把括號在正確的地方。

multi:: Int -> (a -> a) -> a -> a 
multi 0 _ x = x 
multi n f x = multi (n-1) f (f x) 

Cirdec points out你可以用iterate f a !! n做到這一點。

編輯:

如果你想要做的是得到一個功能是f應用n時候你可以做這樣的事情。你就想重複任何功能更換10n(1+)。(或僅部分應用multi

let f = foldr1 (.) (take 10 $ repeat (1+)) 
+0

http://pastebin.com/ECrSKmYT – PyRulez

+0

另外,我在概念上認爲它是「乘以一個函數」。然後我定義這個函數。如果我使用它,那隻會傳遞重複的功能。 – PyRulez

+0

錯誤消息中的行不正確。 '(multi n - 1)'將'multi'應用於'n',然後從結果中減去'1'。即試圖從部分應用的函數中減去1。請注意,我將它改爲'multi(n - 1)'。 – asm