haskell - 为什么 "take"在 haskell 中改变数据类型?

标签 haskell

我正在编写一个从列表中获取元素并返回它们的函数。

我觉得很简单。但是当例如使用“take”时:take 2 [1.2,3,4]

它返回:[1.2,3.0] 当我真正想要 [1.2, 3]

我想创建一个遍历列表并删除不必要的小数位的函数,但是看到 haskell 不接受我与 x & round(x) in 的比较,我无法理解它

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

So A:有没有更简单的解决方案? B:为什么 haskell 不能比较 x 和 round(x)?

最佳答案

你说,“我实际上想要 [1.2, 3] [而不是 [1.2, 3.0]]”。我将其解释为您想要一个列表,其中包含用于小数的 Float 等和用于没有小数部分的数字的 Int 等。

你不能拥有这个。

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 的结果)。

关于haskell - 为什么 "take"在 haskell 中改变数据类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46064670/

相关文章:

postgresql - 使用 postgresql-simple 将 Postgres 间隔转换为 Haskell NominalTimeDiff

haskell - 当编译时参数数量未知时,在 LLVM(haskell 绑定(bind))中添加函数

haskell - Haskell 中的派生和实例之间的区别

haskell - 在没有 `Conkin.Traversable` 的情况下将值更改为 `unsafeCoerce` 中的索引

haskell - 初始编码如何转换为正确的关联结构?

haskell - 数据/类型构造函数和函数之间的区别?

haskell - Haskell中的*>和>>有什么区别?

Haskell 按自定义元组过滤列表

haskell - Haskell 中的复杂数据结构

list - Haskell:从输入列表创建列表元组