Haskell中的类出错
我一直在努力学习haskell的课程,用一个小程序来处理线性方程的表示,但我遇到了一个我不理解的错误。有人能告诉我为什么这个密码吗Haskell中的类出错,haskell,Haskell,我一直在努力学习haskell的课程,用一个小程序来处理线性方程的表示,但我遇到了一个我不理解的错误。有人能告诉我为什么这个密码吗 {-# LANGUAGE FlexibleInstances #-} data Line = Line { m :: Double, b :: Double } deriving( Show, Eq ) class Perpendicular a where perpendicular :: a -> Line instance Perpendicu
{-# LANGUAGE FlexibleInstances #-}
data Line = Line { m :: Double, b :: Double } deriving( Show, Eq )
class Perpendicular a where
perpendicular :: a -> Line
instance Perpendicular (Line -> Double) where
perpendicular (Line m b) b2 = Line m2 b2
where m2 = (-1/m)
给了我这个错误
Couldn't match expected type `Line -> Double'
with actual type `Line'
In the pattern: Line m b
In an equation for `perpendicular':
perpendicular (Line m b) b2
= Line m2 b2
where
m2 = (- 1 / m)
In the instance declaration for `Perpendicular (Line -> Double)'
它看起来好像是一辆自行车 您已将实例编写为
instance Perpendicular (Line -> Double) where ...
这意味着a~(Line->Double)
Vertical
是一个类型为a->Line
的函数,因此在本例中,它将具有具体类型(Line->Double)->Line
。这意味着它的第一个参数必须是一个函数,它接受行
,并返回双精度
。您为它提供了参数Line mb
和b2
,这意味着vertical
应该具有类型Line->Double->Line
,这是一种完全不同的类型。这是因为->
是右关联的,这意味着以下类型是等效的
a -> b -> c -> d
a -> b -> (c -> d)
a -> (b -> (c -> d))
a -> (b -> c -> d)
但事实并非如此
a -> b -> c -> d -- These are not equivalent!!
(a -> b) -> c -> d -- These are not equivalent!!
((a -> b) -> c) -> d -- These are not equivalent!!
(a -> b -> c) -> d -- These are not equivalent!!
看起来您想要的是一个接受变量参数的函数。在Haskell中,这不是最容易做到的事情,并且可能会导致大量样板文件和复杂的数据结构,在牺牲类型安全的同时可能会损害效率。你可以利用元组来解决这个问题,比如
instance Perpendicular (Line, Double) where
perpendicular (Line m b, b2) = Line (-1 / m) b2
instance Perpendicular Line where
perpendicular line = perpendicular (line, 0 :: Double)
注意,这仍然需要FlexibleInstances
,并且还需要0
上的类型注释。这仍然让TypeClass做了它们不该做的事情,但这是法律代码。您还必须在没有声明类型的任何时候对值进行注释,例如
> perpendicular (Line 1 0, 5 :: Double)
Line {m = -1.0, b = 5.0}
> perpendicular (Line 1 0, 5)
No instance for (Perpendicular (Line, t0))
arising from a use of `perpendicular'
The type variable `t0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there is a potential instance available:
instance Perpendicular (Line, Double)
-- Defined at <interactive>:11:10
Possible fix:
add an instance declaration for (Perpendicular (Line, t0))
In the expression: perpendicular (Line 1 0, 5)
In an equation for `it': it = perpendicular (Line 1 0, 5)
>垂直(第10、5行::双行)
行{m=-1.0,b=5.0}
>垂直(第10、5行)
没有(垂直(直线,t0))的实例
由使用“垂直”引起的
类型变量“t0”不明确
可能的修复:添加修复这些类型变量的类型签名
注意:有一个潜在的可用实例:
实例垂直(直线、双圆弧)
--定义时间:11:10
可能的解决方案:
为(垂直(直线,t0))添加实例声明
在表达式中:垂直(第10、5行)
在“it”的方程式中:it=垂直(第10、5行)
您已将实例编写为
instance Perpendicular (Line -> Double) where ...
这意味着a~(Line->Double)
Vertical
是一个类型为a->Line
的函数,因此在本例中,它将具有具体类型(Line->Double)->Line
。这意味着它的第一个参数必须是一个函数,它接受行
,并返回双精度
。您为它提供了参数Line mb
和b2
,这意味着vertical
应该具有类型Line->Double->Line
,这是一种完全不同的类型。这是因为->
是右关联的,这意味着以下类型是等效的
a -> b -> c -> d
a -> b -> (c -> d)
a -> (b -> (c -> d))
a -> (b -> c -> d)
但事实并非如此
a -> b -> c -> d -- These are not equivalent!!
(a -> b) -> c -> d -- These are not equivalent!!
((a -> b) -> c) -> d -- These are not equivalent!!
(a -> b -> c) -> d -- These are not equivalent!!
看起来您想要的是一个接受变量参数的函数。在Haskell中,这不是最容易做到的事情,并且可能会导致大量样板文件和复杂的数据结构,在牺牲类型安全的同时可能会损害效率。你可以利用元组来解决这个问题,比如
instance Perpendicular (Line, Double) where
perpendicular (Line m b, b2) = Line (-1 / m) b2
instance Perpendicular Line where
perpendicular line = perpendicular (line, 0 :: Double)
注意,这仍然需要FlexibleInstances
,并且还需要0
上的类型注释。这仍然让TypeClass做了它们不该做的事情,但这是法律代码。您还必须在没有声明类型的任何时候对值进行注释,例如
> perpendicular (Line 1 0, 5 :: Double)
Line {m = -1.0, b = 5.0}
> perpendicular (Line 1 0, 5)
No instance for (Perpendicular (Line, t0))
arising from a use of `perpendicular'
The type variable `t0' is ambiguous
Possible fix: add a type signature that fixes these type variable(s)
Note: there is a potential instance available:
instance Perpendicular (Line, Double)
-- Defined at <interactive>:11:10
Possible fix:
add an instance declaration for (Perpendicular (Line, t0))
In the expression: perpendicular (Line 1 0, 5)
In an equation for `it': it = perpendicular (Line 1 0, 5)
>垂直(第10、5行::双行)
行{m=-1.0,b=5.0}
>垂直(第10、5行)
没有(垂直(直线,t0))的实例
由使用“垂直”引起的
类型变量“t0”不明确
可能的修复:添加修复这些类型变量的类型签名
注意:有一个潜在的可用实例:
实例垂直(直线、双圆弧)
--定义时间:11:10
可能的解决方案:
为(垂直(直线,t0))添加实例声明
在表达式中:垂直(第10、5行)
在“it”的方程式中:it=垂直(第10、5行)
此解决方案非常有效!你是对的!这个主题实际上是变量输入类型。在第二种情况下,您可以通过编写实例a~Double=>vertical(Line,a),其中…
来消除对显式类型注释的需要。注意这一点,因为它会产生一些非常糟糕的错误消息(请尝试perp(第10行,())
)。这个解决方案非常有效!你是对的!这个主题实际上是变量输入类型。在第二种情况下,您可以通过编写实例a~Double=>vertical(Line,a),其中…
来消除对显式类型注释的需要。注意这一点,因为它将创建一些非常糟糕的错误消息(请尝试perp(第10行,())
)。