我正在做作业,我在做一个演示的例子时遇到了问题,我无法解决它,我尝试了很多事情。我把错误和下面的代码复制给你。
我的代码:
type Height = Float
type Width = Float
type Radius = Float
data Rectangle = Rectangle Height Width
data Circle = Circle Radius
class Shape a where
area :: a -> Float
perimeter :: a -> Float
instance Shape Rectangle where
area (Rectangle h w) = h * w
perimeter (Rectangle b a) = (2*b) + (2*a)
instance Shape Circle where
area (Circle r) = pi * r**2
perimeter (Circle r) = 2*r*pi
type Volume = Float
volumePrism :: (Shape a) => a -> Height -> Volume
volumePrism base height = (area base) * height
surfacePrism ancho largo alto = (2*ancho*largo) + (2*largo*alto) + (2*ancho*alto)
instance Show a => Show (Shape a) where
show (Rectangle h w) = "Rectángulo de base " ++ w ++ "y altura " ++ h错误的意思是:
The first argument of 'Show' should have kind '*'发布于 2014-12-08 21:40:18
Shape是一个类型集,您不能将一个类型集作为另一个类型集的实例。(您也可以将作为类型实例的所有类型设置为不同类型的实例,但这似乎不是您想要做的。)
相反,您似乎希望在Show上实现Rectangle。因此,明确地说:
instance Show Rectangle where
show (Rectangle h w) = "Rectángulo de base " ++ w ++ "y altura " ++ h发布于 2014-12-08 21:40:26
你想做什么是不可能的。Shape是类型类型,而不是数据类型,因此它没有可用于模式匹配的构造函数。你可以做这样的事
instance (Shape a) => Show a where
show shape = "Area: " ++ show (area shape) ++ " Perimeter: " ++ show (perimeter shape)但这似乎不是你想要的。相反,您应该为每种类型分别定义Show:
instance Show Rectangle where
show (Rectangle h w) = "Rectangle with base " ++ show w ++ " and height " ++ show h
instance Show Circle where
show (Circle r) = "Circle with radius " ++ show r关于“种类”的错误对于初学者来说可能是相当神秘的(有时也是经验丰富的哈奇勒人!),但在这种情况下,它是相当简单的。不过,这确实涉及到一个新的概念。在Haskell中,有一个类型的值,例如函数、常量,甚至是一元操作。你也可以谈论“类型的类型”,也就是所谓的类型。有几个您应该了解并乐于使用:*和Constraint。您将看到的大多数类型只涉及*和它们之间的箭头。所有“完全应用”的数据类型都应该有类*,这基本上意味着它不接受任何类型的参数,所以
> :kind Int
Int :: *
> :kind String
String :: *
> :kind IO ()
IO () :: *
> :kind Maybe Int
Maybe Int :: *
> :kind Either String Int
Either String Int :: *但是,您也可以具有更高类型的类型:
> :kind IO -- Note lack of ()
IO :: * -> *
> :kind Maybe
Maybe :: * -> *
> :kind Either
Either :: * -> * -> *每个*只是代表另一个完全应用的类型。最后一个细节很重要,这意味着你不能拥有Either IO Maybe,因为这是一种荒谬的类型。这些也可以是更高的层次:
> import Control.Monad.State
> :kind StateT
StateT :: * -> (* -> *) -> * -> *它的语法与函数类型相同,只是没有种类变量。
另一个你真正需要知道的是Constraint。这是专门为打字员准备的:
> :kind Show
Show :: * -> Constraint
> :kind Num
Num :: * -> Constraint
> :kind MonadState
MonadState :: * -> (* -> *) -> Constraint当完全应用时,它们返回类型类型,而不是数据类型。
如果您好奇,有一些GHC扩展可以让您处理更复杂的类型,甚至允许您为类型或类型指定类型。您可以使用它做一些有趣的技巧,但是这些通常被认为是类型系统的更高级的特性。
发布于 2014-12-08 21:42:25
您的实例声明没有意义。翻译成英文,它会被读成“对于每一个a是Show的实例,a是Shape的一个实例,是Show的一个实例”,或者类似的难以理解的东西。
只需创建Rectangle和Circle Show实例,并将Shape排除在外,除非您希望要求Shape的每个实例都必须是Show的实例,这是需要放入Shape声明中的内容。
https://stackoverflow.com/questions/27367419
复制相似问题