我正在使用Haskell来实现线性代数示例。但是,在声明magnitude
函数时遇到了问题。
我的实施如下:
magnitude :: (Foldable t, Functor t, Floating a) => t a -> a
magnitude = sqrt $ Data.Foldable.foldr1 (+) $ fmap (^2)
我们的想法是magnitude
会接受Vec2D
,Vec3D
或Vec4D
,并返回其组成部分的平方和的平方根。
三种矢量类型中的每一种都实现Functor
和Foldable
。例如,
newtype Vec2D = Vec2D (a, a) deriving (Eq, Show)
instance Functor Vec2D where
fmap f (Vec2D (x, y)) = Vec2D (f x, f y)
instance Foldable Vec2D where
foldr f b (Vec2D (x, y)) = f x $ f y b
但是,我收到了很多错误:
LinearAlgebra.hs:9:13:
Could not deduce (Floating (t a -> a)) arising from a use of `sqrt'
from the context (Foldable t, Functor t, Floating a)
bound by the type signature for
magnitude :: (Foldable t, Functor t, Floating a) => t a -> a
at LinearAlgebra.hs:8:14-60
Possible fix: add an instance declaration for (Floating (t a -> a))
In the expression: sqrt
In the expression: sqrt $ Data.Foldable.foldr1 (+) $ fmap (^ 2)
In an equation for `magnitude':
magnitude = sqrt $ Data.Foldable.foldr1 (+) $ fmap (^ 2)
LinearAlgebra.hs:9:20:
Could not deduce (Foldable ((->) (t a -> a)))
arising from a use of `Data.Foldable.foldr1'
from the context (Foldable t, Functor t, Floating a)
bound by the type signature for
magnitude :: (Foldable t, Functor t, Floating a) => t a -> a
at LinearAlgebra.hs:8:14-60
Possible fix:
add an instance declaration for (Foldable ((->) (t a -> a)))
In the expression: Data.Foldable.foldr1 (+)
In the second argument of `($)', namely
`Data.Foldable.foldr1 (+) $ fmap (^ 2)'
In the expression: sqrt $ Data.Foldable.foldr1 (+) $ fmap (^ 2)
LinearAlgebra.hs:9:41:
Could not deduce (Num (t a -> a)) arising from a use of `+'
from the context (Foldable t, Functor t, Floating a)
bound by the type signature for
magnitude :: (Foldable t, Functor t, Floating a) => t a -> a
at LinearAlgebra.hs:8:14-60
Possible fix: add an instance declaration for (Num (t a -> a))
In the first argument of `Data.Foldable.foldr1', namely `(+)'
In the expression: Data.Foldable.foldr1 (+)
In the second argument of `($)', namely
`Data.Foldable.foldr1 (+) $ fmap (^ 2)'
Failed, modules loaded: none.
我对Functor
或Foldable
感到不舒服 - 我相信这是错误的间接原因。
有人可以向我解释错误消息指向的内容吗?
答案 0 :(得分:5)
您应该将您的功能合并到(.)
而不是($)
的管道中。发生此错误的原因是,例如,Data.Foldable.foldr1 (+)
期望应用于Foldable
类型[a]
,但您实际上是直接将其应用于fmap (^2)
这是一个函数
magnitude :: (Foldable t, Functor t, Floating a) => t a -> a
magnitude = sqrt . Data.Foldable.foldr1 (+) . fmap (^2)
或
magnitude :: (Foldable t, Functor t, Floating a) => t a -> a
magnitude ta = sqrt $ Data.Foldable.foldr1 (+) $ fmap (^2) $ ta
两者都会做得更好。