类型类充当接口(??)

问题描述 投票:0回答:1

在阅读了 Haskell 中的类型类之后,我认为它们就像 Java 接口 您在类型类 (Num) 和任何

data/newtype
(Foo) 声明的类型中定义一组方法,如果它想成为
part of
类型类,则必须实现该类型类的所有方法。

但这有什么用呢? 这与多态性有何关系? 是参数化多边形还是临时多边形?

这就是 ghci 中定义

Num
类型类的方式

type Num :: * -> Constraint
class Num a where
  (+) :: a -> a -> a
  (-) :: a -> a -> a
  (*) :: a -> a -> a
  negate :: a -> a
  abs :: a -> a
  signum :: a -> a
  fromInteger :: Integer -> a
  {-# MINIMAL (+), (*), abs, signum, fromInteger, (negate | (-)) #-}
    -- Defined in ‘GHC.Num’
instance Num Double -- Defined in ‘GHC.Float’
instance Num Float -- Defined in ‘GHC.Float’
...

首先,第一个

type Num :: * -> Constraint
是什么意思(?) 之后,它说,如果一个类型
a
想要成为约束/部分Num,它应该实现以下功能。 下面显示了该类型类的一些实例,如
Double
Float
这看起来像java接口。

所以,为了让

Foo
成为这个Num
成员
我们需要做类似的事情

instance Num Foo where 
  (+) foo1 foo2 = foo1
   ...

但是它有什么用(?) 我明白它们是如何定义的

haskell polymorphism typeclass
1个回答
0
投票

首先,kind签名

* -> Constraint
意味着
Num
是采用类型(
*
)并返回
Constraint
的东西。

A

Constraint
是一个接口,即类型必须以实现某些方法的形式满足的契约。

多态性与此相关,因为您可以使用约束来编写对类型通用的函数,但有一些更细粒度的要求。例如:假设您有一个函数想要在列表中查找元素。类型可能是

find :: a -> [a] -> Int

其中返回的类型是位置,类型变量

a
是对象和列表的类型。但是等等...在该方法的任何实现中,在某些时候,我必须使用
x :: a
as :: [a]
=
中的元素进行比较。所以它在
a
上并不是真正通用的,我们需要强加一个
Constraint
来表示“
a
必须实现与
=
运算符相等的概念”。那么类型签名就变成了

find :: Eq a => a -> [a] -> Int

=>
不像函数箭头,它更像是在说“只要满足约束
Eq a
,那么......”

© www.soinside.com 2019 - 2024. All rights reserved.