Haskell 如何使用类型同义词和代数数据类型?
对于以下代码,如何指定函数storePhone将Int存储为哪种电话号码类型HomePhone或WorkPhoneHaskell 如何使用类型同义词和代数数据类型?,haskell,types,Haskell,Types,对于以下代码,如何指定函数storePhone将Int存储为哪种电话号码类型HomePhone或WorkPhone type HomePhone = Int type WorkPhone = Int data Phone = HomePhone | WorkPhone storePhone :: int -> Phone storePhone num = num main :: IO () main = print $ storePhone 12345678
type HomePhone = Int
type WorkPhone = Int
data Phone = HomePhone
| WorkPhone
storePhone :: int -> Phone
storePhone num = num
main :: IO ()
main = print $ storePhone 12345678
这个问题是我正在做的一个副题的简化版。
我有一个模块,可以将文件解析为相关的数据类型,如示例中的电话类型。所有数据都是双重的,但语义不同。在另一个模块中,我有使用数据的方法。每种方法都采用不同的数据类型排列(如家庭电话、工作电话)作为参数。我本可以制作家庭电话和工作电话数据类型,甚至是新类型,但这会让使用数据的方法看起来很混乱,有很多模式匹配之类的东西。所以我只是想知道我是否可以简化数据类型AKA电话,使它更优雅,仍然是类型安全的。干杯
我想我应该做以下事情
type HomePhone = Int
type WorkPhone = Int
data Phone = HomePhone HomePhone
| WorkPhone WorkPhone
在当前形式下,电话类型不能存储任何电话号码。它有两个构造函数,都接受零参数,因此不能存储任何内容。构造函数的名称等于您前面定义的类型名称这一事实并不意味着什么
您可能打算这样做:
type PhoneNumber = String -- Storing phone numbers as ints is a bad idea
data PhoneType = HomePhone
| WorkPhone
deriving Show
data Phone = Phone PhoneType PhoneNumber
deriving Show
storePhone :: PhoneNumber -> PhoneType -> Phone
storePhone number typ = Phone typ number
main :: IO ()
main = print $ storePhone "12345678" HomePhone
我认为sepp2k很好地回答了你的问题,但我将尝试解释,为什么我认为你首先会有这个问题。类型和值之间以及类型构造函数和值构造函数之间存在差异
Phone = Phone
在本例中,左侧是类型,右侧是值。请注意,类型和值可以具有相同的名称。编译器会明白你的意思。基本上,在类型声明和数据声明中,您指的是类型,在函数实现中,您指的是值
Phone = NoPhone
| Phone Int
在本例中,NoPhone是一个值,而右手边的Phone是一个值构造函数,因为它使用Int类型的值来生成值。左侧仍然是一种类型
Container a = NotEmpty a
| Empty
在本例中,Container是一个类型构造函数,因为您可以给它一个Int类型来获取一个类型——在本例中,它将是Container Int类型。Empty是一个值,NotEmpty是一个值构造函数,它接受您为a选择的任何类型的值——让我们调用该类型T,以生成Container T类型的值
在您的示例中,混合了类型和值的概念
type HomePhone = Int
type WorkPhone = Int
这说明HomePhone和WorkPhone只是Int类型的不同名称
这表示任何类型的Phone都具有值HomePhone或值WorkPhone。重要的是,这些值与前面声明的具有相同名称的类型同义词不同
storePhone :: int -> Phone
这表示storePhone接受Int类型的值并返回Phone类型的值
这是一个问题。在这一行中,num是Int类型的值,但是您返回num,并且您刚才在类型声明中说您将返回Phone类型的值,即HomePhone值或WorkPhone值。如果您想变得愚蠢,但遵守您的类型声明,您可以这样做
storePhone num = if num > 0 then HomePhone else WorkPhone -- silly, but compiles :)
它甚至可以编译吗?编译器可以在错误和警告方面为您提供许多有用的信息。
storePhone num = num
storePhone num = if num > 0 then HomePhone else WorkPhone -- silly, but compiles :)