展开自定义列表类型

时间:2016-02-13 19:14:08

标签: f#

如果我有以下内容:

type StringList = StringList of string list
let sl = StringList [ "Hello, "; "World" ]
let length = List.length sl

然后抛出以下编译器错误:

This expression was expected to have type 'a list but here has type StringList

我的理解是StringListoption“包裹”string list,那么如何“解包”它以便我可以在其上调用List方法?

1 个答案:

答案 0 :(得分:4)

问题是您的StringList类型正在定义一个新类型,它是string list的包装器。可以在string list上运行的函数对你的包装器不起作用,因为它们对它一无所知。

你可以将StringList定义为类型别名 - 所以不是定义一个新类型,它只是一个方便的名称:

type StringList = string list
let sl : StringList = [ "Hello, "; "World" ]
let length = List.length sl

另一种选择是在调用string list之前提取List.length值:

type StringList = StringList of string list

let stringListlength (StringList(slData)) = 
    List.length slData

let sl = StringList [ "Hello, "; "World" ]
stringListlength sl

在第一种方法中,您只是定义一个名称,但编译器不会对其进行任何检查,因此仅在您希望在类型注释(例如)中使用该名称使其可读时才有用。

在第二种方法中,您确实定义了一种新类型,因此您确保使用StringList的每个人都将使用您定义或使用它的函数。

这里很难说什么是好方法,因为StringList不是很好的例子 - 它并没有真正传达string list以外的任何其他信息。