0

对于以下代码,如何指定函数 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

这个问题是我正在做的一个附带项目的问题的简化版本。我有一个将文件解析为相关数据类型的模块(也就是示例中的电话类型)。所有数据都是 Double 但语义不同。在另一个模块中,我有使用数据的方法。每种方法都将数据类型(又名 HomePhone、WorkPhone)的不同排列作为参数。我本可以制作 HomePhone 和 WorkPhone 数据类型甚至是新类型,但它会使使用数据的方法看起来很混乱,有很多模式匹配和东西。所以只是想知道我是否可以简化数据类型(又名电话),以便它更优雅一点并且仍然类型安全。干杯! 我想我应该做以下事情?

type HomePhone = Int
type WorkPhone = Int

data Phone = HomePhone HomePhone 
           | WorkPhone WorkPhone 
4

2 回答 2

4

在其当前形式中,该Phone类型无法存储任何电话号码。它有两个构造函数,它们都接受零参数,因此不能存储任何东西。构造函数的名称与您之前定义的类型名称相同这一事实并不意味着什么。

您可能打算这样:

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
于 2013-02-09T12:12:10.243 回答
4

我认为 sepp2k 很好地回答了您的问题,但我将尝试解释,为什么我认为您首先遇到了问题。类型和值之间以及类型构造函数和值构造函数之间存在差异。

Phone = Phone

在这个例子中,左边是一个类型,右边是一个值。请注意,类型和值都可以具有相同的名称。编译器会弄清楚你的意思。基本上,在类型声明和数据声明中,您的意思是类型,而在函数实现中,您的意思是值。

Phone = NoPhone
      | Phone Int

在这个例子中,NoPhone是一个值,右边Phone是一个值构造函数,因为它需要一个类型的值Int来生成一个值。左侧仍然是一个类型。

Container a = NotEmpty a
            | Empty

在这个例子中,Container是一个类型构造函数,因为你可以给它一个类型,比如Int得到一个类型——在这种情况下就是 type Container IntEmpty是一个值,并且NotEmpty是一个值构造函数,它采用您碰巧选择的任何类型的值a- 让我们称之为 type T,以产生一个 type 的值Container T

在您的示例中,您混合了类型和值的概念。

type HomePhone = Int
type WorkPhone = Int

这就是说,HomePhone只是WorkPhone类型的不同名称Int

data Phone = HomePhone
           | WorkPhone

这表示任何类型Phone都有 valueHomePhone或 value WorkPhone。重要的是,这些值与您之前声明的具有相同名称的类型同义词不同。

storePhone :: int -> Phone

这表示 storePhone 接受一个 type 的值Int并返回一个 type 的值Phone

storePhone num = num

这是个问题。在这一行中,num 是 type 的值Int,但是您返回 num,而您刚刚在类型声明中说您将返回 type 的值Phone,即 valueHomePhone或 value WorkPhone。如果你想傻,但符合你的类型声明,你可以这样做

storePhone num = if num > 0 then HomePhone else WorkPhone -- silly, but compiles :)
于 2013-02-09T13:59:16.320 回答