我试图让SML/NJ在顶层打印出一个结果,而不是在任何地方放置#符号.
根据一些旧的文档(以及2001年该新闻组的帖子),应该可以使用 Compiler.Control.Print.printDepth
但是,在SML/NJ版本110.7上,这只是一个错误:
- Compiler.Control.Print.printDepth := 100;
stdIn:1.1-30.8 Error: unbound structure: Control in path Compiler.Control.Print.printDepth
Run Code Online (Sandbox Code Playgroud) 如果你在Haskell中编写生物信息学算法,你可能会使用代数数据类型来表示核苷酸:
data Nucleotide = A | T | C | G
Run Code Online (Sandbox Code Playgroud)
你会在标准ML或OCaml中做同样的事情,我假设(我从来没有真正使用过).
类型的值Nucleotide
可以清楚地包含在两位中.但是,这样做会导致访问时间比每个Nucleotide
值使用一个字节要慢,因为您需要使用二元运算符选择两个感兴趣的位.
因此,在决定如何表示代数数据类型时,编译器必须在内存效率和计算效率之间进行固有的权衡.此外,由于值可以是可变大小的事实,因此代数数据类型在内存中的表示变得更加复杂:
data Maybe a = Just a | Nothing
Run Code Online (Sandbox Code Playgroud)
显然,Maybe a
表单的值在Just a
逻辑上大于表单的值Nothing
.在这样一个极端的例子中:
data Hulk a b c d e = Big a b c d e | Little
Run Code Online (Sandbox Code Playgroud)
你肯定不希望存储Little
值null指针或值中包含的五个值的零Big
值.我假设你只是使用堆分配的可变大小的内存,在开头有一个构造函数ID(例如,0
for Big
和1
for Little
).但是,如果要Hulk
在堆栈上存储值(表示更快),则必须将空白内存与Little
值一起存储,以使该类型的所有值Hulk
都具有相同的大小.另一个权衡.
Simon Marlow在之前的StackOverflow问题中回答了关于GHC的一般问题.但是,我有三个相关的问题仍然没有答案:
Nucleotide …
memory haskell functional-programming sml algebraic-data-types
我过去在SML做过一些工作,但现在我开始涉及更有趣的部分.
使用该abstype...with...end
构造,我可以制作东西,但隐藏其实现细节.我还可以创建我想要制作的东西的签名,并使用:>
运算符来构建一个遵循该签名的结构,以保持隐藏实现细节.
签名/结构不仅仅是一种更通用的弃用版本吗?对于签名/结构我不能做的弃用,我该怎么办?为什么我要使用abstype?
在此先感谢您的帮助!
举个例子:
signature SET = sig
type set
val empty: set
val insert: int * set -> set
val member: int * set -> bool
end
structure Set :> SET = struct
type set = int list
val empty = []
fun insert(x, s) = x::s
fun member(x, []) = false
| member(x, h::t) = (x = h) orelse member(x, t)
end
Run Code Online (Sandbox Code Playgroud)
似乎至少和...一样强大
abstype AbsSet = absset of int list with
val empty …
Run Code Online (Sandbox Code Playgroud) 这更像是一个风格问题而不是其他任何问题.鉴于以下代码:
case e1 of (* datatype type_of_e1 = p1 | p2 *)
p1 => case e11 of (* datatype type_of_e11 = NONE | SOME int *)
NONE => expr11
| SOME v => expr12 v
| p2 => case e21 of (* datatype type_of_e21 = NONE | SOME string *)
NONE => expr21
| SOME v => expr22 v
Run Code Online (Sandbox Code Playgroud)
有没有办法解决types of rules don't agree
因尝试将e11模式匹配到p2而导致的错误,而不是将p1的表达式括在括号中?在P2模式还有另外一个case语句,避免"只是切换模式"答案;-).
更新:更改代码以反映更具体的情况
是o
组合物操作者(例如val x = foo o bar
,其中foo
和bar
是两个功能),仅在单参数的函数和/或功能可用与参数相等数量?如果没有,是什么,比如说,组成语法foo(x,y)
用bar(x)
.
我目前正在处理一个三级流程,我需要一些信息才能访问和更新.信息也是三级的,这样一个级别的过程可能需要在其级别和更高级别访问/更新信息.
type info_0 = { ... fields ... }
type info_1 = { ... fields ... }
type info_2 = { ... fields ... }
Run Code Online (Sandbox Code Playgroud)
fun0
会用a做一些东西info_0
,然后将它传递给fun1
a info_1
,然后返回结果info_0
并继续,fun1
用另一个调用另一个info_1
.同样的情况发生在较低级别.
我目前的代表有
type info_0 = { ... fields ... }
type info_1 = { i0: info_0; ... fields ... }
type info_2 = { i1: info_1; ... fields ... }
Run Code Online (Sandbox Code Playgroud)
在fun2
,更新info_0
变得非常混乱:
let fun2 (i2: info_2): info_2 =
{ …
Run Code Online (Sandbox Code Playgroud) 我知道分号在REPL中用作终结符.但我很困惑何时在源文件中使用它们.
例如,之后没有必要val x = 1
.但如果我之后省略它use "foo.sml"
,编译器会抱怨它.
那么,使用分号的规则是什么?
我是SML的新手,我想确保我真正了解基础知识.SML中的类型和数据类型有什么区别,以及何时使用哪个?