声明我自己的类型并在Haskell中的函数中使用它们

时间:2013-11-18 22:41:38

标签: haskell types algebraic-data-types

我正在努力提高对Haskell中代数数据类型的理解。这个例子没有多大意义,但我只是想学点东西。代码应该是非常明显的!假如我有一些代码:

type Pig = String
type Lion = String
type Feed = [(Char,Char)]
type Visitors = [(Char,Char)]
type Costs = (Int,Int,Int)

data AnimalHome = Farm Pig Pig Pig Feed | Zoo Lion Lion Lion Feed Visitors

orders :: Char -> AnimalHome -> Costs -> Char
orders stuff Farm bert donald horace specialFeed (cost1,cost2,cost3) = some code here

到目前为止这是否正确,还是有些事我做错了?

2 个答案:

答案 0 :(得分:2)

正如@GabrielGonzalez已经建议的那样,您需要将Farm bert donald horace specialFeed放在括号中并处理Zoo案例:

orders :: Char -> AnimalHome -> Costs -> Char
orders stuff (Farm bert donald horace specialFeed) (cost1,cost2,cost3) = undefined
orders stuff (Zoo l1 l2 l3 feed visitors) (c1, c2, c3) = undefined

答案 1 :(得分:1)

我建议使用更多结构化类型,以便类型系统可以警告您,如果您将访问者视为Feed(在宣传方面往往会严重下降)。

NEWTYPE

newtype Pig = Pig String
newtype Lion = Lion String
newtype Feed = Feed [(Char,Char)]

此处Pig的存储方式相同,但代码不同 - newtype被编译出来,但为您提供类型安全,以免意外混淆。

数据与类型

让我们尝试一些不同的东西:

data Visitor = Visitor Char Char -- same data storability as (Char,Char)
type Visitors = [Visitor]

最好使用type来创建同义词 - Visitors[Visitor]类型相同,但您可以使用Visitors作为轻微缩写。

记录

现在让我们使用Costs的记录类型:

newtype Costs = Costs {capital::Int, consumables::Int, impulse::Int}

所以我可以创建一个类似somecosts = Costs {capital=3,consumables=5,impulse=7}或仅somecosts = Costs 3 5 7的值,但我可以免费获得访问者函数:capital somecosts3,{{1} }是consumables somecosts

重复的字段?

我的DBA感到担忧

5

我觉得应该

data AnimalHome = Farm Pig Pig Pig Feed | Zoo Lion Lion Lion Feed Visitors

全部使用

将会,

data AnimalHome = Farm [Pig] Feed | Zoo [Lion] Feed Visitors

您可以使用orders :: Char -> AnimalHome -> Costs -> Char orders stuff (Farm pigs specialFeed costs) = -- some code here 参数上的访问器函数,或嵌套模式匹配

costs