2016-02-13 4 views
1

Если у меня есть следующий:Unwrapping пользовательского типа списка

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 

Я понимаю, что StringList является option «обертывание» string list, так как я могу «развернуть» его, чтобы на нем можно было называть List?

+0

_Context: только что начал изучать F # ._ –

ответ

3

Проблема заключается в том, что ваш тип 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 

в первом подходе, вы просто определение имени, но компилятор не будет делать какие-либо проверки на нем, так что это только полезно, если вы хотите использовать имя в аннотации типа (например,) t o сделать их читаемыми.

Во втором подходе вы действительно определяете новый тип, поэтому убедитесь, что все, работающие с StringList, будут использовать функции, которые вы определяете или работаете с ним.

Трудно сказать, что здесь хороший подход, потому что StringList не очень хороший пример - на самом деле он не передает никакой дополнительной информации за string list.

+0

Спасибо за ваш ответ. Я делаю обертку, чтобы получить безопасность типов, поэтому ваш второй вариант - именно то, чего я не хватало. Большое спасибо! –

Смежные вопросы