我是 Haskell 的初學者,我正在嘗試創建一個包含 2 個元素的元組,第一個是整數,第二個是浮點數。例子:
f1 n = [(x, x) | x <- [1 .. n]]
f2 n = [(x, 1 / x) | x <- [1 .. n]]
> f1 5
[(1,1),(2,2),(3,3),(4,4),(5,5)]
> f2 5
[(1.0,1.0),(2.0,0.5),(3.0,0.3333333333333333),(4.0,0.25),(5.0,0.2)]
f1 的行為符合預期,回傳一個包含兩個整數的元組串列。
f2 回傳一個包含兩個浮點數的元組串列,但我期望它回傳一個包含一個整數和一個浮點數的元組串列。
我如何將第一個元組元素型別保留為整數,以便輸出f2 5如下所示:[(1,1.0),(2,0.5),(3,0.3333333333333333),(4,0.25),(5,0.2)]
uj5u.com熱心網友回復:
發生這種情況的原因是編譯器看到1/x,這不僅要求結果是浮動的(Fractional實際上是),而且還要求引數是浮動的x。這是因為 Haskell 中的數字運算子具有完全相同的型別簽名
(/) :: Fractional a => a -> a -> a
即編譯器推斷它也x必須已經具有浮點型別,因此元組的左元素最終為浮點數。
您可以通過不除以x自身而是允許轉換來防止這種情況:
Prelude> [(x, 1 / fromIntegral x) | x <- [1 .. 9]]
[(1,1.0),(2,0.5),(3,0.3333333333333333),(4,0.25),(5,0.2),(6,0.16666666666666666),(7,0.14285714285714285),(8,0.125),(9,0.1111111111111111)]
此外,當型別看起來不正確時,您應該始終嘗試的一件事是添加顯式簽名。通過這種方式,您還可以強制以其他可能更合適的型別執行計算,例如Rational:
Prelude> [(x, 1 / fromIntegral x) | x <- [1 .. 9]] :: [(Int, Rational)]
[(1,1 % 1),(2,1 % 2),(3,1 % 3),(4,1 % 4),(5,1 % 5),(6,1 % 6),(7,1 % 7),(8,1 % 8),(9,1 % 9)]
此外,如果您嘗試一些不起作用的東西,而不是默默地意外結果,您將得到一個明確的編譯器錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/355866.html
標籤:哈斯克尔
