2017-09-05 46 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的结果)。

相关问题