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
是类型class
Integral
的成员,并且函数肯定会返回一个
浮动
数字的列表。这根本没有任何意义

有人能解释错误发生的原因,以及我应该如何修复它吗?

问题是,如果数字总是映射到相同类型的数字,请注意类型签名中的
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
类型,因此可以将其推断为
整数
浮动
类型。