2017-02-17 35 views
2

我試圖定義一個函數來返回每個第n個roots of unity
這將編譯,無法使函數更具多態性

unity n = map (cis.(*2).(*pi).(/n)) [0..(n-1)] 

但其類型默認爲unity :: (Enum a, Floating a) => a -> [Complex a]
當然,n需要是一個整數,因爲統一的根不是另外定義的;但返回的複數數字必須具有浮點座標;即它們不能是Complex Int s。但是,下面的代碼不會編譯

unity :: (Integral a, Floating b) => a -> [Complex b] 
unity n = map (cis . (* 2) . (* pi) . (/ n)) [0..(n - 1)] 

(/)因爲和(*)每個cis約束返回類型(或復座標中的cis的情況下型)是一樣的參數類型;所以我得到的錯誤

無法比擬預期的「B」型與實際輸入「a」

有沒有一種方法,我可以強制參數是一個整數,而不強迫複數有整體組件?

回答

4

所有你需要做的是與fromIntegral強迫你Integral參數爲Num當你的代碼期望相同類型的返回類型,即作爲參數cis(*)(/)的值。雖然n只直接進入(/),所以這就是你需要擔心:

unity :: (Integral a, Floating b) => a -> [Complex b] 
unity n = map (cis . (* 2) . (* pi) . (/ (fromIntegral n)) . fromIntegral) [0..(n-1)] 
+1

短:'團結N =順。 (2 * pi/fromInteral N *)。 fromIntegral <$> [0 .. n-1]'。 – leftaroundabout

+0

啊..我試過了(* 2 * pi/fromInteral n),失敗了,沒有意識到反過來是可能的 –

+1

是的,這是因爲'infixl 7 *,/',所以'(* 2 * pi/n)'將被解析爲,例如'((* 2 * pi)/ n)',這不起作用。反過來,它只是解析'((2 * pi/n)*)'。 – leftaroundabout