Haskell支持面向对象编程吗

Haskell支持面向对象编程吗,haskell,Haskell,它是否支持声明和实现分离(Java中的接口和类)之类的概念 如何限制访问(如Java中的访问修饰符)?如何在Haskell中分离声明和实现? 在Haskell中,您可以定义一个与面向对象类截然不同的类,因此不要让这个名称欺骗您。使用关键字类,可以声明函数名和类型签名,这些可以在其他地方为特定数据类型实例化(实现) 例如,typeclass定义了hash函数,该函数可以将任何实例化的数据类型转换为Int。有一个新的,时髦的数据类型,你想能够散列?好的,创建一个Hashable的实例。最常见的数据类

它是否支持声明和实现分离(Java中的接口和类)之类的概念


如何限制访问(如Java中的访问修饰符)?

如何在Haskell中分离声明和实现?

在Haskell中,您可以定义一个与面向对象类截然不同的类,因此不要让这个名称欺骗您。使用关键字
,可以声明函数名和类型签名,这些可以在其他地方为特定数据类型实例化(实现)

例如,typeclass定义了
hash
函数,该函数可以将任何实例化的数据类型转换为
Int
。有一个新的,时髦的数据类型,你想能够散列?好的,创建一个Hashable的实例。最常见的数据类型由定义哈希表的模块实例化(参见链接文档中的“实例”)

类型类不是定义接口的唯一方法。通常被低估的方法是一个简单的旧数据结构。由于Haskell具有第一类函数,因此可以定义一个将函数作为字段的数据结构:

data ShuttleInterface =
  SI { launch    :: Delay -> IO Handle
     , deploy    :: Payload -> IO ()
     , getStatus :: IO Status
     }
您的函数可以构建或使用此数据结构:

deployAllSensors :: ShuttleInterface -> IO ()
deployAllSensors shuttle = do
    status <- getStatus shuttle
    let notDeployed = filter (not . deployed) (sensors status)
    when (isOrbiting status) (mapM_ deploySensor notDeployed)

-- we used the well-known Haskell functions: filter, not, , when, mapM_
-- and some supporting functions were assumed:
isOrbitting :: Status -> Bool
deploySensor :: Sensor -> IO ()
sensors :: Status -> [Sensor]
deployed :: Sensor -> Bool
deployAllSensors::ShuttleInterface->IO()
展开所有传感器梭式传感器=do
状态布尔
部署传感器::传感器->IO()
传感器::状态->[传感器]
部署::传感器->布尔
如何限制对Haskell中数据的访问?

为了提供抽象,Haskell使用。为了保护字段,开发人员声明一个数据类型,但不导出它的构造函数——相反,他们只导出一组维护所需不变量的安全原语

例如,该模块提供了一个平衡树。如果有人仅仅使用
分支
的原语来声明地图,就无法保证平衡,因此制造商没有出口这些原语。映射的构造必须依赖于从数据导出的内容。映射(以及那些由于在同一模块中而可以访问/使用构造函数的映射),例如
fromList
empty
singleton
,还有一大堆修饰符。

有关如何在Haskell中实现OO概念的详细说明,请参见Oleg Kiselyov和Ralf Laemmel。但正如Antal在评论中所说,不要试图用Haskell编写Java程序


请记住,对象是穷人的闭包,闭包是穷人的对象。

类型类确实是唯一可以远程提醒OO概念的构造,在本例中,是在接口上。不过,与java不同,类型类不是类型

类型类的一个好处是,我可以使完全不相关的、已经存在的类型成为类型类的成员。然而在java中,有时人们会想:我使用的包org.A中的类A和com.B中的类B应该是从第三个包中实现接口Y,但是没有办法不需要大量的样板代码、额外的间接指令、编组等


顺便说一句,作为一名上了年纪的程序员,我想指出“声明和实现的分离”本身与OOP无关。仅仅因为大多数OO语言支持它,并不意味着这个概念在OO发明之前很久都不为人所知。有兴趣的年轻人认为OO主流化之前的编程必须处于“石器时代”的水平,他们可能会查找MODULA,例如,在MODULA中,声明和实现的分离不仅是可能的,而且是由语言强制执行的。

值得一提的是。它们允许您以可组合的方式编写
a.b.c.d.e
“表达式”


可以为每个数据结构定义
。所以在某种意义上,
是哈斯克尔的一等公民。它可以命名、存储、两个
-s可以组合,等等。

我只是偶然发现了某个东西,请参阅一个具有完整机制的可运行程序(尽管完整代码仍然非常短)

我从来没有想过OO可以用Haskel 以这样一种直截了当的方式

构造对象:


!o请注意,如果您在Haskell中工作,则不应尝试编写Java程序,反之亦然。使用这种语言,而不是违背规则,通常会产生更干净的代码。然而,这只不过是一次练习。我不会用Java风格来编写Haskell,下面有一些很好的答案,但我建议你不要把这样的东西看作是“OO”特性。例如,在Haskell中,封装和隐藏实现的主要单元是模块,而不与任何特定的数据结构绑定。模块化设计在用于面向对象编程之前是一件好事!类似地,Haskell中的类型类明确拒绝在一个地方编写数据结构及其行为的OO式想法,但仍然有效地分离接口和实现。AFAIK即使在C中,也可以划分声明和实现。另外,访问限制并不是一个真正的OOP概念。数据隐藏可能是,但这更多的是关于如何使用事物,而不是语言施加的限制。+1,也许有必要指出,由于所有数据都是不可变的,因此字段保护虽然可能,但不如具有可变数据类型的OOP语言中的字段保护那么重要。我发现了另一个“类似OOP”的有用示例Haskell中的语法:@Ingo所需要的不是防止修改的能力,而是防止修改的能力取决于。如已显示的
sun.misc.Unsafe
。可以说,OOP是关于抽象内部的。在模块中隐藏实现细节仍然是一种好的做法,即使您具有不变性。这是非常重要的