我一直在尝试用一个小程序来学习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)'
看起来好像忽略了b2。
答案 0 :(得分:5)
您已将实例编写为
instance Perpendicular (Line -> Double) where ...
这意味着a ~ (Line -> Double)
。 perpendicular
是一个类型为a -> Line
的函数,因此对于此实例,它将具有具体类型(Line -> Double) -> Line
。这意味着它的第一个参数必须是一个带Line
并返回Double
的函数。您已为其提供了Line m b
和b2
参数,这意味着perpendicular
应该具有类型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
上的类型注释。这仍然使得类型组做了他们并不意味着的事情,但它是合法的代码。只要它没有声明的类型,你也必须注释一个值,例如。
> 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)