haskell - 如何获得与向量一起使用的通用平均值以在 Haskell 中编译?
问题描述
我试过:
import Data.VectorSpace -- ^/
import Data.AdditiveGroup -- sumV
import Data.Foldable -- length
avg :: (Foldable f, VectorSpace a) => f a -> a
avg xs = sm ^/ sz -- could be just ^*(1/sz)
where sm = sumV xs
sz = fromIntegral (length xs)
并得到:
Distancesumcurves.hs:11:10: error:
• Could not deduce (Fractional (Scalar a))
arising from a use of ‘^/’
from the context: (Foldable f, VectorSpace a)
bound by the type signature for:
avg :: (Foldable f, VectorSpace a) => f a -> a
at Distancesumcurves.hs:10:1-46
• In the expression: sm ^/ sz
In an equation for ‘avg’:
avg xs
= sm ^/ sz
where
sm = sumV xs
sz = fromIntegral (length xs)
Distancesumcurves.hs:13:13: error:
• Could not deduce (Num (Scalar a))
arising from a use of ‘fromIntegral’
from the context: (Foldable f, VectorSpace a)
bound by the type signature for:
avg :: (Foldable f, VectorSpace a) => f a -> a
at Distancesumcurves.hs:10:1-46
• In the expression: fromIntegral (length xs)
In an equation for ‘sz’: sz = fromIntegral (length xs)
In an equation for ‘avg’:
avg xs
= sm ^/ sz
where
sm = sumV xs
sz = fromIntegral (length xs)
当然,我可以专门为向量写一个,然后继续我的生活,但是 Haskell 的通用特性的意义何在。用一种不那么迂腐的语言,我已经完成了它,它可以正常工作,并且可以重用。在 Haskell 中,我必须在这里写一个问题或回归代码重复。我认为这是语言的失败。
这不是我第一次对 Haskell 泛型感到沮丧。我已经超过了 Graham Hutton 所著的《Haskell 编程》一书的水平。对我来说下一步/书/文章应该是什么?这样当我知道我想要什么并且它是正确的时,我就不会与编译器争论。在这种情况下,我缺乏的只是语言技术技能。如果我错了,请随时纠正我。
编辑:
似乎在上下文中工作
approximateCurve :: [Point] -> Path
approximateCurve pts = [] -- TODO
where center = avg pts
avg vs = (sum vs) ^/ (fromIntegral (length vs))
sum = foldr (^+^) (0,0)
解决方案
在这种情况下,我将添加错误消息中建议的附加约束,以获取avg :: (Foldable f, VectorSpace a, Fractional (Scalar a)) => f a -> a
.
Fractional
暗示Num
,所以无需赘述Num
。如果你添加它也没有什么坏处——这个功能并没有变得不那么通用。
就一般建议而言,我认为在类型错误的指导下编写大量通用函数是最好的方法。通常添加建议的约束就足够了;其他时候你真的想要更通用的签名,并且需要找出哪个函数带来了不需要的约束。
推荐阅读
- python - 在 Windows 上使用韩语语言环境的 Python datetime.strptime
- php - 如何使用 php 使用 mysql 数据库中的列号获取值
- javascript - 嵌套异步/等待是反模式吗?
- bash - 卷曲命令在 dockerfile 的 load.sh 中不起作用
- c - 不能在 C 中重用相同的字符串(字符数组)
- python - 如何在 Selenium 中打印 webdriver 的所有内容?
- android - 如何在演示者中为 2 种不同用法传递单个上下文参数?
- java - 如何在 Hibernate 中进行映射
- reactjs - 从redux获取数据后如何使用onChange函数
- getopt - getopt longoptions 示例无法按预期工作