试图了解SML选项结构

2 functional-programming wildcard sml smlnj option

好的,所以我开始学习一个类的SML,我坚持使用选项结构.到目前为止我对这个例子的看法是:

datatype suit = spades|hearts|clubs|diamonds;
datatype rank = ace|two|three|...|j|q|k|joker;
type card = suit*rank;
Run Code Online (Sandbox Code Playgroud)

我的讲师试图解释选项结构的使用,说不是所有卡片都必须有套装; 笑话者没有与他们相关的诉讼.因此,在设计功能性服装以获得卡片的套装时,我们有以下内容:

datatype 'a option = NONE | SOME of 'a;
fun getsuit ((joker,_):card):suit option = NONE
  | getsuit ((_,s):card):suit option = SOME s;
Run Code Online (Sandbox Code Playgroud)

但是使用emacs,我得到两个错误,一个说明模式和约束如何不一致,

pattern: rank * ?.suit
constraint: rank * suit
Run Code Online (Sandbox Code Playgroud)

另一个说法表达式和结果类型如何不一致.

expression: ?.suit option
result type: suit option
Run Code Online (Sandbox Code Playgroud)

这是讲师提供的代码,因此如果它导致错误,它们没有多大帮助."?"是什么意思?为什么会出现?我该如何正确定义这个功能?

Fai*_*aiz 5

option你定义它并不是一个真正的问题.你有秩序suitrank你的card模式错误的方式:

尝试:

datatype 'a option = NONE | SOME of 'a;

fun getsuit ((_, joker):card):suit option = NONE
  | getsuit ((s, _):card):suit option = SOME s;
Run Code Online (Sandbox Code Playgroud)

我的ML版本可能会以不同的方式打印错误,所以我不确定如何解释?.等等的含义.但是如果你一点一点地采取它就很简单:

尝试

(clubs, ace);
Run Code Online (Sandbox Code Playgroud)

解释器(或emacs,如果你正在使用的那个)告诉你类型是a的产物suit * rank.这是ML的工作类型推断,但您可以指定类型(您期望),如下所示:

(clubs, ace): suit*rank;
Run Code Online (Sandbox Code Playgroud)

要么

(clubs, ace): card; (* Works, since card is defined as (suit*rank) *)
Run Code Online (Sandbox Code Playgroud)

你不会有任何抱怨.但显然你会这样做

(clubs, ace): rank*suit;
Run Code Online (Sandbox Code Playgroud)

要么

(clubs, ace): card; (* card is defined as (rank*) *)
Run Code Online (Sandbox Code Playgroud)

您对getsuit参数的类型(它必须是a card或兼容的(suit*rank)产品)设置了约束,但模式是类型(rank*?)或者(?*rank)两者都不兼容(suit*rank).