Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell中的类出错_Haskell - Fatal编程技术网

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

我一直在努力学习haskell的课程,用一个小程序来处理线性方程的表示,但我遇到了一个我不理解的错误。有人能告诉我为什么这个密码吗

{-# 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行,())
)。