Haskell - 实例约束绑定

时间:2014-07-11 05:10:56

标签: haskell

我正在学习Haskell编程语言来理解函数式编程范例。

我正在尝试编写以下代码

class Area shape where
area :: (Num n) => shape n -> n

data Quadrilateral t = Rectangle {length::t, width::t} | Square {side::t} deriving(Show)

data CircularShape t = Circle {radius::t} deriving(Show)

instance Area Quadrilateral where
    area (Rectangle l w) =  l * w
    area (Square s ) = s * s

instance Area CircularShape where
    area (Circle r) = pi * r * r

main = do
        putStrLn . show . area $ Rectangle 10.0 20.0
        putStrLn . show . area $ Square 10
        putStrLn . show . area $ Circle 10.0

以下是code

的链接

我收到错误,

Error occurred
ERROR line 13 - Cannot justify constraints in instance member binding
*** Expression    : area
*** Type          : (Area CircularShape, Num a) => CircularShape a -> a
*** Given context : (Area CircularShape, Num a)
*** Constraints   : Floating a

我无法理解此错误的确切原因。在添加CircularShape数据及其对应的Area类型类实例之前,此代码工作正常。

如果我想同时使用Quadrilateral和CircularShape,我该如何解决这个问题?

2 个答案:

答案 0 :(得分:4)

由于我们使用不同的编译器,因此我会向您显示错误窗口的输出。

box.hs|14 col 23 error| Could not deduce (Floating n) arising from a use of ‘pi’
|| from the context (Num n)
||   bound by the type signature for
||              area :: Num n => CircularShape n -> n
||   at /Users/evan/box.hs:14:5-8
|| Possible fix:
||   add (Floating n) to the context of
||     the type signature for area :: Num n => CircularShape n -> n
|| In the first argument of ‘(*)’, namely ‘pi’
|| In the first argument of ‘(*)’, namely ‘pi * r’
|| In the expression: pi * r * r

基本上,在你的类型类声明中,n被绑定到Num中,如果你想将它与pi相乘,这是一个浮点类型。

尝试将Num更改为Floating

class Area shape where
    area :: (Floating n) => shape n -> n

你可能会收到类似“默认为双重”的警告,这是因为haskell中有两种浮动类型(即Float和Double)

答案 1 :(得分:1)

将区域的类型签名更改为

area:: (Floating n) => shape n -> n

您的代码无效,因为与pi的乘法需要类型约束Floating a

同时使用print代替putStrLn . show