在Haskell中处理复杂组合的POD(OO中的普通旧数据)的推荐方法是什么?

我是Haskell的新手。 在静态类型的OO语言(例如,Java)中,所有复杂的数据结构都表示为类和实例。对象可以具有许多属性(字段)。另一个对象可以是该字段的值。可以使用其名称访问这些字段,并按类静态键入。最后,这些对象构建了彼此链接的巨大对象图。大多数程序都使用这样的数据图。 如何在Haskell中归档这些功能?     
已邀请:
Haskell具有代数数据类型,其可以描述结构的结构或联合,使得给定类型的某些东西可以容纳许多不同字段集中的一个。这些字段可以通过位置或通过带有记录语法的名称进行设置和访问。 请参见此处:http://learnyouahaskell.com/making-our-own-types-and-typeclasses     
如果你真的有没有行为的数据,这很好地映射到Haskell记录:
data Person = Person { name    :: String
                     , address :: String }
            deriving (Eq, Read, Show)

data Department = Management | Accounting | IT | Programming
                deriving (Eq, Read, Show)

data Employee = Employee   { identity   :: Person
                           , idNumber   :: Int
                           , department :: Department }
              | Contractor { identity :: Person
                           , company  :: String }
              deriving (Eq, Read, Show)
这表示
Person
Person
,其中有
name
address
(均为
String
s); a
Department
Management
Accounting
IT
Programming
;
Employee
Employee
,其中
identity
(a
Person
),
idNumber
(an
Int
),
department
(a
Department
),或者是
Contractor
,其中
identity
(a
Person
)和
company
(a
String
) 。
deriving (Eq, Read, Show)
行使您可以比较这些对象是否相等,读取它们并将它们转换为字符串。 一般来说,Haskell数据类型是联合(也称为和)和元组(也称为产品)的组合.1
|
s表示选择(联合):
Employee
Employee
Contractor
Department
是其中之一四件事等等。一般来说,元组的写法如下:
data Process = Process String Int
这说
Process
(除了是一个类型名称)是一个类型为
String -> Int -> Process
的数据构造函数。因此,例如,
Process "init" 1
,或
Process "ls" 57300
。 A
Process
必须同时存在
String
Int
。上面使用的记录符号只是这些产品的语法糖;我也可以写
data Person = Person String String
,然后定义
name :: Person -> String
name (Person n _) = n

address :: Person -> String
address (Person _ a) = a
但是,记录符号对于复杂的数据结构来说可能很好。 另请注意,您可以将Haskell类型与其他类型进行参数化;例如,一个三维点可能是
data Point3 a = Point3 a a a
。这意味着
Point3 :: a -> a -> a -> Point3 a
,所以人们可以写
Point3 (3 :: Int) (4 :: Int) (5 :: Int)
得到一个
Point3 Int
,或者
Point3 (1.1 :: Double) (2.2 :: Double) (3.3 :: Double)
得到一个
Point3 Double
。 (或者
Point3 1 2 3
得到一个
Num a => Point3 a
,如果你看过类型类和重载的数字文字。) 这是表示数据图表所需的内容。但是,请注意:人们从命令式语言转换为功能性语言的一个问题 - 或者实际上,在任何两种不同的范例之间(C到Python,Prolog到Ruby,Erlang到Java,等等) - 继续尝试解决问题旧的方式。您尝试建模的解决方案可能无法以易于编程技术的方式构建,即使问题是这样。例如,在Haskell中,考虑类型非常重要,其方式与Java不同。同时,为这些类型实现行为的方式完全不同:高阶函数捕获了您在Java中看到的一些抽象,但也有一些不容易表达的抽象(
map :: (a -> b) -> [a] -> [b]
filter :: (a -> Bool) -> [a] -> [a]
foldr :: (a -> b -> b) -> b -> [a] -> b
) )。因此,请保持您的选择开放,并考虑以功能性方式解决您的问题。当然,在这种情况下,也许你可以全力以赴。但是在探索新语言时请记住这一点。玩得开心 :-) 1:递归:例如,你可以用
data Tree a = Leaf a | Branch a (Tree a) (Tree a)
表示二叉树。     

要回复问题请先登录注册