【发布时间】:2019-12-18 16:13:21
【问题描述】:
(问题在底部以粗体显示。)
我正在检查Chris Okasaki's Purely Functional Data Structures,我试图将第一个数据结构及其实现从标准 ML 转换为 F#。 ML如下(从书中翻译):
signature STACK =
sig
type 'a Stack
val empty : 'a Stack
val isEmpty : 'a Stack -> bool
val cons : 'a * 'a Stack -> 'a Stack
val head : 'a Stack -> 'a (* raises EMPTY if stack is empty *)
val tail : 'a Stack -> 'a Stack (* raises EMPTY if stack is empty *)
end
及其第一个实现:
structure List:STACK =
struct
type 'a Stack = 'a list
val empty = []
fun isEmpty s = null s
fun cons (x,s) = x :: s
fun head s = hd s
fun tail s = tl s
end
为了清楚起见,它的第二个实现:
structure CustomStack:STACK =
struct
datatype 'a Stack = NIL | CONS of 'a * 'a Stack
val empty = NIL
fun isEmpty NIL = true | isEmpty _ = false
fun cons (x, s) = CONS(x, s)
fun head NIL = raise EMPTY
| head (CONS(x, s)) = x
fun tail NIL = raise EMPTY
| tail (CONS(x, s)) = s
end
我几乎可以将 ML signature 移植到 F# 中:
type 'a Stack = Stack of 'a
type 'a STACK =
val Stack : 'a Stack
val empty : 'a Stack
val isEmpty : 'a Stack -> bool
val cons : 'a * 'a Stack -> 'a Stack
val head : 'a Stack -> 'a
val tail : 'a Stack -> 'a Stack
尽管很明显,没有办法将 F# 类型实现为任何实质性的东西,但这段代码仍然可以编译,因为没有构造函数并且它不被识别为接口(并且不能写成一个,因为val Stack 和val empty 不是函数)。它在fsi 中编译为一个类,但显然没有构造函数或任何实现它的东西。之前sn-p的fsi签名是:
type 'a Stack = | Stack of 'a
type 'a STACK =
class
val Stack: 'a Stack
val empty: 'a Stack
val isEmpty: 'a Stack -> bool
val cons: 'a * 'a Stack -> 'a Stack
val head: 'a Stack -> 'a
val tail: 'a Stack -> 'a Stack
end
1.有没有办法在 .NET 生态系统中利用它,拥有像这样的纯类型,实用与否?另外,这是否被认为是某种能够创建不可实现数据类型的错误?
2。无论如何,是否可以在不使用接口和抽象类的情况下在 F# 中实现标准 ML 数据结构,或者由于 .NET 的结构方式,它们是强制性的?
【问题讨论】:
-
现在没有时间给出完整的答案,但有两件事:1) 几乎可以将 ML 签名移植到 F# 并不是巧合,因为 F# 的语法被采用来自 ML(我认为来自 OCaml)。 2) 您可能有兴趣查看github.com/fsprojects/FSharpx.Collections 的源代码以了解已经实现的内容。
标签: .net types f# sml translate