如何解决Haskell-将整数列表映射到其平方根
我创建了一个小函数,将整数列表映射到其平方根。代码本身很简单:
f x = map sqrt [1..x]
使用默认类型推断,它可以成功加载,但是该函数可以接受Floating
个typeclass值,而我只是希望它接受Integer
。因此,我在其顶部添加了类型注释。
f :: (Integral a,Floating b) => a -> [b]
f x = map 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
是类型类Integral
的成员,并且该函数肯定会返回Floating
数字的列表。只是没有任何意义。
任何人都可以解释错误发生的原因以及如何解决吗?
解决方法
问题在于sqrt :: Floating a => a -> a
将始终将数字映射到相同类型的数字,请注意类型签名中的a -> a
。它还要求数字必须是Floating
的实例,尽管从技术上讲,您可以将类型设为Integral
和Floating
的实例,但这没有多大意义。
如果您写[ 1 .. x ]
,则会生成与x
相同类型的项目列表。因此,如果x
为Integral a => a
,则[ 1 .. x ]
的类型为Integral a => [a]
(和相同的a
)。但是,您的类型签名表明,对于每种Integral
类型a
,您都可以生成Floating
类型b
的任何元素列表。
您可以使用fromIntegral :: (Integral a,Num b) => a -> b
将整数转换为另一种数字,因此可以这样写:
f :: (Integral a,Floating b) => a -> [b]
f x = map (sqrt . fromIntegral) [1..x]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。