Module ocaml构造模块(超级初学者)

Module ocaml构造模块(超级初学者),module,ocaml,Module,Ocaml,我不熟悉使用ocaml进行模块编程。我制作了一个字典模块,如 module type DICT = sig type key type 'a dict ... val lookup : 'a dict -> key -> 'a option ... end module DictList : DICT with type key = string = struct type key = string type '

我不熟悉使用ocaml进行模块编程。我制作了一个字典模块,如

module type DICT =
  sig
    type key
    type 'a dict
    ...
    val lookup : 'a dict -> key -> 'a option
    ...
  end


module DictList : DICT with type key = string =
  struct
    type key = string
    type 'a dict = (key * 'a) list

    ...
    **let rec lookup d k =
        match d with
        | [] as dict -> None
        | (key, value)::tl as dict -> if( key = k ) then (key, value)
                                      else lookup tl k**
    ...
  end
查找dk在字典d中搜索键k。如果找到该键,它将返回该项,否则,它将不返回任何项。然而,我得到了一个错误,它说

错误:此表达式的类型为“a*”b 但应为“c列表”类型的表达式

在查找功能。
问题是什么?我如何解决它?

查找中
匹配
表达式的所有分支应具有相同的类型-对应于
查找
的返回类型:
'a选项
。因此,“found”大小写应该返回
一些值,而不是
(键,值)

查找中
匹配的
表达式的所有分支应该具有相同的类型-对应于
查找的返回类型:
'a选项
。因此,“found”案例应该返回
一些值,而不是
(key,value)
,这里有两个问题(没有一个给出您声称得到的错误)

第一个问题:您的
查找
函数的类型不一致

一个分支返回
None
,因此类型应该是
'a option
。 另一个分支返回
(键,值)
,因此类型应该是
'a*'b

如何修复?将
(键,值)
更改为
一些(键,值)

不幸的是,还有一个问题

第二个问题:您的
查找
函数与其在模块类型中的定义不对应

如果您查看
DICT
的定义,您将看到
查找
'a DICT->key->'一个选项

现在,在您对
DictList
模块的定义中,
key
string
,因此
lookup
应该是
'a dict->string->'a选项
,其中
a
是存储在词典中的值的类型。这意味着您不能返回
Some(key,value)
,因为
lookup
将具有签名
'a dict->string->(string*'a)选项
。只返回
一些值

所以,你的定义应该是

模块DictList:DICT类型key=string=
结构
类型键=字符串
键入'a dict=(键*'a)列表
让rec查找k=
匹配
|[]->无
|(键,值)::tl->if(键=k)然后其他一些值查找tlk
结束

这里有两个问题(没有一个给出您声称得到的错误)

第一个问题:您的
查找
函数的类型不一致

一个分支返回
None
,因此类型应该是
'a option
。 另一个分支返回
(键,值)
,因此类型应该是
'a*'b

如何修复?将
(键,值)
更改为
一些(键,值)

不幸的是,还有一个问题

第二个问题:您的
查找
函数与其在模块类型中的定义不对应

如果您查看
DICT
的定义,您将看到
查找
'a DICT->key->'一个选项

现在,在您对
DictList
模块的定义中,
key
string
,因此
lookup
应该是
'a dict->string->'a选项
,其中
a
是存储在词典中的值的类型。这意味着您不能返回
Some(key,value)
,因为
lookup
将具有签名
'a dict->string->(string*'a)选项
。只返回
一些值

所以,你的定义应该是

模块DictList:DICT类型key=string=
结构
类型键=字符串
键入'a dict=(键*'a)列表
让rec查找k=
匹配
|[]->无
|(键,值)::tl->if(键=k)然后其他一些值查找tlk
结束

我想我误解了什么。因为查找的定义是
('a dict->key->'a option)
,而dict的定义是
(key*'a)list
。因此,我认为返回值应该是
(key*'a)
,即
'a
。不,你错了。假设
'a
int
。然后
查找的类型
(在模块类型中定义)是
int dict->key->int option
。什么是
int-dict
——这是另一个故事,但是
lookup
已经被定义为返回
int-option
;您可以完美地实现
DICT
,它将
'a DICT
定义为
int
,将
查找dk
定义为一个函数,该函数始终返回
一些(类型'a中的一些常量值)
。它不会有任何好处,但它也适合模块类型。我想我误解了什么。因为查找的定义是
('a dict->key->'a option)
,而dict的定义是
(key*'a)list
。因此,我认为返回值应该是
(key*'a)
,即
'a
。不,你错了。假设
'a
int
。然后
查找的类型
(在模块类型中定义)是
int dict->key->int option
。什么是
int-dict
——这是另一个故事,但是
lookup
已经被定义为返回
int-option
;您可以完美地实现
DICT
,它将
DICT
定义为
int
,将
查找dk
定义为始终返回
S的函数