gpt4 book ai didi

functional-programming - 如何在 SML/NJ 中创建和使用我自己的结构/签名?

转载 作者:行者123 更新时间:2023-12-04 08:40:33 24 4
gpt4 key购买 nike

我是函数式编程的新手,我想创建自己的名为 Dictionary 的结构/签名。到目前为止,我在名为 dictionary-en.sml 的文件中有这个:

(* The signature DICTIONARY defines a type and a programming interface for
the dictionary data structure. The data structure allows us to store
data in the form of (key, value) pairs and to query the data using a key. *)
signature DICTIONARY =
sig

(* The structure has to implement a dictionary type. It defines key type,
which has to support equality checking, and a value type for the data
stored in the dictionary. *)
type (''key, 'value) dict

(* Creates an empty dictionary. *)
val empty: (''key, 'value) dict

(* Returns true if a key exists in the dictionary. *)
val exists: (''key, 'value) dict -> ''key -> bool

end

我在文件 solution.sml 中有这个:

structure Dictionary :> DICTIONARY =
struct
type (''key, 'value) dict = (''key * 'value) list

val empty = []

fun exists dict key =
case dict of
[] => false
| (k, _ )::rep => if k = key
then true
else exists rep key
end

但我不知道如何使用它。当我在 REPL 中写道:

- Dictionary.exists [(3,"c"), (5, "e"), (7, "g")] 3;

我遇到了这个错误:

stdIn:1.2-3.7 Error: operator and operand do not agree [tycon mismatch]
operator domain: (''Z,'Y) Dictionary.dict
operand: ([int ty] * string) list
in expression:
Dictionary.exists ((3,"c") :: (5,"e") :: (<exp>,<exp>) :: nil)

有人可以帮帮我吗?我不知道我做错了什么。

最佳答案

在函数中

fun exists dict key =
case dict of
[] => []
| (k, _ )::rep => if k = key
then true
else exists rep key

我发现了两个问题:

  • 你不能在一个地方返回 [] 而在另一个地方返回 true
  • P orelse Q代替if P then true else Q

你正在使用 :> 这意味着模块是 opaque ,所以你只能访问签名中指定的东西。签名中没有提到内部列表表示,因此您不能将 dict 称为列表,即使您可能知道它是这样实现的。这是一项功能。

我可能会为 member 调用 exists,因为 List.exists 是一个高阶谓词,例如List.exists (fn x => x > 5) [3, 6, 9]。您也可以偏离任何标准库命名,并说 containsKeycontainsValue,或类似的名称。

除了 molbdnilo 建议的 insert 函数之外,您可能还想要一个 fromList 函数。

这是一个重构版本(为简洁起见省略了评论,但我认为您的评论很好!):

signature DICTIONARY =
sig
type (''key, 'value) dict

val empty: (''key, 'value) dict
val member: ''key -> (''key, 'value) dict -> bool
val insert: (''key * 'value) -> (''key, 'value) dict -> (''key, 'value) dict
val fromList: (''key * 'value) list -> (''key, 'value) dict
end

structure Dictionary :> DICTIONARY =
struct
type (''key, 'value) dict = (''key * 'value) list

val empty = []

fun member key [] = false
| member key ((key2, _)::dict) =
key = key2 orelse member key dict

fun insert (key, value) [] = [(key, value)]
| insert (key, value) ((key2, value2)::dict) =
if key = key2
then (key, value) :: dict
else (key2, value2) :: insert (key, value) dict

fun fromList pairs = foldl (fn (pair, dict) => insert pair dict) empty pairs
end

但是由于您正在构建字典模块,因此您需要考虑两件事:

  1. 使使用某种二叉树作为内部表示成为可能,要求键可以排序,而不是比较相等性
  2. 由于标准 ML 没有像 ''key 这样的特殊语法来表示可以订购的东西(Haskell 将其概括为 type classes ,但标准 ML 只有特殊语法 ''key),这是使用 functors 的好例子,它是给高阶模块的名称,也就是参数化模块。

这是一个您可以填写的示例签名、仿函数和结构:

signature ORD = sig
type t
val compare : t * t -> order
end

signature DICT = sig
type key
type 'value dict

val empty: 'value dict
val member: key -> 'value dict -> bool
val insert: key * 'value -> 'value dict -> 'value dict
val fromList: (key * 'value) list -> 'value dict
end

functor Dict (Ord : ORD) :> DICT = struct
type key = Ord.t
type 'value dict = (key * 'value) list

val empty = ...
fun member _ _ = raise Fail "not implemented"
fun insert _ _ = raise Fail "not implemented"
fun fromList _ = raise Fail "not implemented"
end

此时你可以将type 'value dict改成使用二叉树,当你需要决定在这个二叉树中是向左还是向右时,你可以这样写:

case Ord.compare (key1, key2) of
LESS => ...
| EQUAL => ...
| GREATER => ...

当你需要一个字典,其中键是某种特定的 orderable 类型时,你可以使用这个仿函数创建一个模块:

structure IntDict = Dict(struct
type t = int
val compare = Int.compare
end)

structure StringDict = Dict(struct
type t = string
val compare = String.compare
end)

另见 Standard ML functor examples更多示例。

关于functional-programming - 如何在 SML/NJ 中创建和使用我自己的结构/签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53484202/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com