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

时间:2011-02-12 03:28:36

标签: haskell pod

我是Haskell的新手。

在静态类型的OO语言(例如,Java)中,所有复杂的数据结构都以类和实例的形式呈现。对象可以具有许多属性(字段)。另一个对象可以是该字段的值。可以使用其名称访问这些字段,并按类静态键入。最后,这些对象构建了彼此链接的巨大对象图。大多数程序都使用这样的数据图。

如何在Haskell中归档这些功能?

2 个答案:

答案 0 :(得分:5)

如果你真的有没有行为的数据,这很好地映射到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)

这表示PersonPerson,其中nameaddressString s}; DepartmentManagementAccountingITProgramming; EmployeeEmployee identity(一个Person),一个idNumber(一个Int)和一个{department {1}} {(Department),或者是Contractor identity(a Person)和companyString })。使用deriving (Eq, Read, Show)行可以比较这些对象是否相等,读取它们并将它们转换为字符串。

通常,Haskell数据类型是联合(也称为 sums )和元组(也称为产品)的组合。 1 |表示选择(联合):Employee EmployeeContractorDepartment是四件事之一,等等。一般来说,元组的写法如下:

data Process = Process String Int

这表示Process(除了是类型名称)是一个类型为String -> Int -> Process的数据构造函数。因此,例如Process "init" 1Process "ls" 57300Process必须 一个StringInt才能存在。上面使用的记录符号只是这些产品的语法糖;我也可以写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],{{1想到了{}和filter :: (a -> Bool) -> [a] -> [a]。因此,请保持您的选择开放,并考虑以功能性方式解决您的问题。当然,在这种情况下,也许你可以全力以赴。但是在探索新语言时请记住这一点。玩得开心: - )


1:和递归:例如,您可以使用foldr :: (a -> b -> b) -> b -> [a] -> b来表示二叉树。

答案 1 :(得分:1)

Haskell具有代数数据类型,它可以描述结构的结构或联合,使得给定类型的某些东西可以容纳许多不同字段集中的一个。这些字段可以通过位置或通过带有记录语法的名称进行设置和访问。

见这里:http://learnyouahaskell.com/making-our-own-types-and-typeclasses