2017-09-05 44 views
2

我正在寫一個函數,它從列表中獲取元素並返回它們。爲什麼haskell中的「需要」更改數據類型?

很簡單,我以爲。但是,當使用「走」在例如:take 2 [1.2,3,4]

返回:[1.2,3.0]當我真正想[1.2, 3]

我想用於創建列表並削減不必要的小數進入功能,但我不能讓我的頭周圍看到Haskell沒有接受我隨x &圓(X)在

function :: [a] -> [a] 
function(x:xs) 
if x == round(x) = round(x):function xs 
else x:function xs 

所以比較:有沒有簡單的解決方案? B:爲什麼Haskell比較x與round(x)?

+8

您是否試過'[1.2,3]'沒有'take'?如果沒有,我建議你這樣做。這根本不是「錯誤」。 –

+0

它看起來像你試圖用來定義'function'的語法不正確。表達式'x == round(x)'是非常好的,但是語法如下所示:'function(x:xs)| x == round(x)= round(x):function xs;函數(x:xs)= x:函數xs' –

+0

@TannerSwett表達式'x == round x'很好,但沒有具體的類型(在標準庫中),你可以給'x'它類型正確。 –

回答

6

take不改變列表元素的類型。啓動GHCi並遵循。我的提示是>>>

>>> :t [1.2,3,4] 
[1.2,3,4] :: Fractional t => [t] 

這表示列表元素有一些Fractional類型。

>>> :t [1.2,3.0,4.0] 
[1.2,3.0,4.0] :: Fractional t => [t] 

GHCi在這裏也說同樣的事情。到底是怎麼回事?

>>> :t 2 
2 :: Num t => t 
>>> :t 2.0 
2.0 :: Fractional t => t 

沒有小數的數字文字被推斷爲有一些Num類型。推導出一個帶有小數的數字字符,它有一些Fractional類型。要將兩個元素放在同一個列表中,它們必須具有相同的類型。 22.0的常見類型是什麼?

>>> :t 2 `asTypeOf` 2.0 
2 `asTypeOf` 2.0 :: Fractional a => a 

所有Fractional類型Num類型等信息,爲22.0的常見的類型是一些Fractional類型。

>>> [1.2,3,4] 
[1.2,3.0,4.0] 

我們可以從所有的元素都被推斷爲Fractional類型列表的打印見。默認爲Double

要從列表中刪除不必要的小數,您必須更具體地說明您希望此列表擁有哪種類型。 Int的列表沒有小數,Double的列表總是有小數。單個列表不能同時包含IntDouble類型的元素。

11

你說,「我其實想[1.2, 3] [而不是[1.2, 3.0]]」。我將其解釋爲意味着您需要一個包含分數的Float s或類似的列表,以及對於沒有小數部分的數字的Int s等。

你不能擁有這個。

Haskell中的所有列表均勻:每個元素具有相同的類型。

有一些事情可以做;例如,您可以標記聯合,標準示例爲Either。所以

[Left 1.2, Right 3] :: [Either Double Integer] 

會很好;但您需要明確標記每個元素。

這或多或少地是爲什麼x == round x不起作用的答案:(==)運算符接受兩個相同類型的參數;而通常round無法返回與其參數相同類型的值。你可能會喜歡properFraction代替:

> properFraction 3 
(3,0.0) 
> properFraction 1.2 
(1,0.19999999999999996) 

可以檢查這個第二部分,以確定您的號碼是否爲整數或沒有(當它是,第一部分將是round的結果)。

相關問題