Haskell-将整数列表映射到其平方根
我创建了一个小函数,将整数列表映射到它们的平方根。代码本身很简单:Haskell-将整数列表映射到其平方根,haskell,Haskell,我创建了一个小函数,将整数列表映射到它们的平方根。代码本身很简单: fx=map sqrt[1..x] 使用默认类型推断,它可以成功加载,但该函数可以接受浮点值typeclass值,我只希望它接受整数s。所以我在上面添加了一个类型注释 f::(积分a,浮动b)=>a->[b] f x=地图sqrt[1..x] 出乎我的意料,它未能加载。在GHCi的REPL上引发了一个错误: 1.hs:48:7: error: • Couldn't match type ‘a’ with ‘b’
fx=map sqrt[1..x]
使用默认类型推断,它可以成功加载,但该函数可以接受浮点值
typeclass值,我只希望它接受整数
s。所以我在上面添加了一个类型注释
f::(积分a,浮动b)=>a->[b]
f x=地图sqrt[1..x]
出乎我的意料,它未能加载。在GHCi的REPL上引发了一个错误:
1.hs:48:7: error:
• Couldn't match type ‘a’ with ‘b’
‘a’ is a rigid type variable bound by
the type signature for:
f :: forall a b. (Integral a, Floating b) => a -> [b]
at 1.hs:47:1-41
‘b’ is a rigid type variable bound by
the type signature for:
f :: forall a b. (Integral a, Floating b) => a -> [b]
at 1.hs:47:1-41
Expected type: [b]
Actual type: [a]
• In the expression: map sqrt [1 .. x]
In an equation for ‘f’: f x = map sqrt [1 .. x]
• Relevant bindings include
x :: a (bound at 1.hs:48:3)
f :: a -> [b] (bound at 1.hs:48:1)
|
48 | f x = map sqrt [1..x]
| ^^
我完全失去了理智,不知道错误在说什么。它似乎抱怨结果类型应该是[a]
,而不是[b]
。但这是荒谬的,因为a
是类型classIntegral
的成员,并且函数肯定会返回一个浮动
数字的列表。这根本没有任何意义
有人能解释错误发生的原因,以及我应该如何修复它吗?问题是,如果数字总是映射到相同类型的数字,请注意类型签名中的a->a
。它还要求数字是浮点
的实例,虽然从技术上讲,您可以创建一个同时是整数
和浮点
实例的类型,但这没有多大意义
如果编写[1..x]
,将生成一个与x
类型相同的项目列表。因此,如果x
是Integral a=>a
,那么[1..x]
的类型是Integral a=>[a]
(这是相同的a
)。但是,您的类型签名表示,对于每个积分类型a
,您可以生成a浮动类型b
的任何元素列表
您可以利用将整数转换为另一种类型的数字,因此您可以将其写成:
f :: (Integral a, Floating b) => a -> [b]
f x = map (sqrt . fromIntegral) [1..x]
f::(积分a,浮动b)=>a->[b]
Fx=map(sqrt.fromIntegral)[1..x]
奇怪的是,GHCi假设sqrt
可以接受Integral
值并不断推导。为什么?我的意思是,如果它能提示像sqrt这样的东西,需要一个浮点值,但得到了积分值,我会更容易找出错误。@Stephen.W:它没有。如果您编写map sqrt[1..x]
它将假定x
具有类型Floating a=>a
。您可以在ghci中使用:t\x->map sqrt[1..x]
查询类型,它将指定浮动a=>a->[a]
。请注意,如果您写入5
,则它只是Num
类型,因此可以将其推断为整数
或浮动
类型。