haskell - Show Haskell 的实例

标签 haskell

我正在做作业,在执行 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/

相关文章:

graphics - Haskell 像素绘图库 Linux

postgresql - 使用 postgresql-simple 执行动态查询

haskell - Haskell RNG 和状态

optimization - Haskell:列表/向量/数组性能调优

haskell - Haskell 中使用 Data.Map 进行动态编程?

haskell - 'f' 在仿函数的 fmap 函数中代表什么?

haskell - 图结构中的并查找

performance - Haskell 的严格折叠真的使用线性空间吗?

debugging - 有调试生产功能程序的实际经验吗?

haskell - 函数获得四个参数而不是三个 - 为什么这不会中断?