我是Haskell的新手。
在静态类型的OO语言(例如,Java)中,所有复杂的数据结构都以类和实例的形式呈现。对象可以具有许多属性(字段)。另一个对象可以是该字段的值。可以使用其名称访问这些字段,并按类静态键入。最后,这些对象构建了彼此链接的巨大对象图。大多数程序都使用这样的数据图。
如何在Haskell中归档这些功能?
答案 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)
这表示Person
是Person
,其中name
和address
(String
s}; Department
是Management
,Accounting
,IT
或Programming
; Employee
是Employee
identity
(一个Person
),一个idNumber
(一个Int
)和一个{department
{1}} {(Department
),或者是Contractor
identity
(a Person
)和company
(String
})。使用deriving (Eq, Read, Show)
行可以比较这些对象是否相等,读取它们并将它们转换为字符串。
通常,Haskell数据类型是联合(也称为 sums )和元组(也称为产品)的组合。 1 |
表示选择(联合):Employee
是 Employee
或Contractor
,Department
是四件事之一,等等。一般来说,元组的写法如下:
data Process = Process String Int
这表示Process
(除了是类型名称)是一个类型为String -> Int -> Process
的数据构造函数。因此,例如Process "init" 1
或Process "ls" 57300
。 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]
,{{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