我正在做作业,在执行 Show 实例时遇到问题,但无法解决,我尝试了很多方法。我将错误和代码复制给您。
我的代码:
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 '*'
最佳答案
你想做的事情是不可能的。 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
关于“种类”的错误对于初学者(有时是经验丰富的 Haskellers!)来说可能相当神秘,但在本例中它相当简单。不过,这确实涉及一个新概念。在 Haskell 中,您拥有具有类型的值,例如函数、常量,甚至单子(monad)操作。您还可以谈论“类型的类型”,即所谓的种类。您应该了解并熟悉以下几个内容:*
和 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 :: * -> (* -> *) -> * -> *
它的语法与函数类型相同,只是没有类型变量。
您真正需要了解的另一个是约束
。这是专门针对类型类的:
> :kind Show
Show :: * -> Constraint
> :kind Num
Num :: * -> Constraint
> :kind MonadState
MonadState :: * -> (* -> *) -> Constraint
完全应用后,它们返回类型类,而不是数据类型。
如果您好奇,GHC 扩展可以让您处理更复杂的类型,甚至允许您指定类型或类型类的类型。您可以使用它执行一些有趣的技巧,但这些通常被认为是类型系统的更高级功能。
关于haskell - Show Haskell 的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27367419/