在Haskell中继承数据类型?

and*_*gps 1 haskell

是否可以继承haskell中的数据类型?让我们假设:

data Data1 = Data1
    { name :: String
    } deriving (Show)
Run Code Online (Sandbox Code Playgroud)

在同一个模块上,我想做类似的事情:

data Data2 = Data1 
let x = Data2 "Something"
Run Code Online (Sandbox Code Playgroud)

我希望Data2有这个领域name,'继承' Data1.

我知道那data Data2 = Data1不是那样做的.所以,我想知道是否有办法做到这一点.

谢谢

安德烈

Dan*_*zer 5

Haskell没有继承.事实上,从你的脑海中消除所有与OOP相关的想法.

相反,从构图角度思考是一种更有成效的方法.

newtype Data1 = Data1 {name :: String}
              deriving Show

newtype Data2 = Data2 {wrappedD1 :: String}
Run Code Online (Sandbox Code Playgroud)

现在你可以拥有

nameD2 :: Data2 -> String
nameD2 = name . wrappedD1
Run Code Online (Sandbox Code Playgroud)

但是,如果要对这两个操作使用相同的名称,则需要"ad-hoc多态",即重载.在Haskell的土地上,我们有类型的类型

data D1 = D1 {nameD1 :: String} deriving Show
data D2 = D2 {wrappedD1 :: D1} deriving Show

class Named a where
  name :: a -> String

instance Named Data1 where
 name = nameD1
instance Named Data2 where
  name = name . wrappedD1
Run Code Online (Sandbox Code Playgroud)

现在我们可以用name两个D1D2.这类似于接口的概念.

Tangent:你使用顶层语法,let foo = bar但在Haskell中,我们只let在GHCi中使用绑定,因为GHCi的工作方式有些奇怪.而是只使用foo = bar.

  • @ 9000我更多地说这是因为尝试编写围绕子类型层次结构的Java代码只会导致不可读/低效的Haskell.类型类<=>接口是一个有用的类比,但像所有类比一样,它最终失败了.认为多参数类型类,类型类没有类型作为第一个参数和类似 (5认同)