在SML中声明函数的类型

在SML中声明函数的类型,sml,ml,Sml,Ml,我不熟悉ML,但在其他使用类型推断的语言中,我已经学会了一种习惯,即每当右侧的推断对人类读者来说是显而易见的时候,就忽略该类型的事物,而每当该推断对人类来说不是显而易见的时候,就显式地声明该类型的事物。我喜欢这个约定,并希望在我的ML代码中继续使用它 我有以下等效的函数声明示例: fun hasFour [] = false | hasFour (x::xs) = (x = 4) orelse hasFour xs 相当于 val rec hasFour: int list -&

我不熟悉ML,但在其他使用类型推断的语言中,我已经学会了一种习惯,即每当右侧的推断对人类读者来说是显而易见的时候,就忽略该类型的事物,而每当该推断对人类来说不是显而易见的时候,就显式地声明该类型的事物。我喜欢这个约定,并希望在我的ML代码中继续使用它

我有以下等效的函数声明示例:

fun hasFour      [] = false
  | hasFour (x::xs) = (x = 4) orelse hasFour xs
相当于

val rec hasFour: int list -> bool =
 fn      [] => false
  | (x::xs) => (x = 4) orelse hasFour xs
我喜欢后一种形式,这不仅是因为我在阅读时更容易弄清楚函数的类型,而且还因为它明确声明了函数的类型,因此,如果我在实现中出错,就不可能意外声明语法有效但类型错误的东西,以后调试起来会比较困难

我的问题是:我想使用
fun
而不是
val rec
,因为匿名
fn
只能接受一个参数。因此,后一种技术在语法上对
int->int->bool
之类的函数无效。有没有办法在
fun
中显式声明类型?或者我在这篇文章中列出了所有首选的替代方案,并且应该简单地遵循其中一种模式吗?我能找到的使用显式类型声明的
fun
的唯一方法是向模式中的每个参数添加一个类型声明,这非常难看和可怕,如下所示:

fun hasFour ([]:int list):bool = false
  | hasFour            (x::xs) = (x = 4) orelse hasFour xs
一位同事向我展示了一些遵循如下模式的代码:

fun hasFour      [] = false
  | hasFour (x::xs) = (x = 4) orelse hasFour xs

val _ = op hasFour: int list -> bool

通过声明一个未命名变量并将其设置为强制类型的函数实例,我们有效地实现了所需的结果,但是
val
必须出现在完全定义的函数下面,而这对于人类读者来说不太明显,除非你只是习惯这种模式并学会期待它。

最近我问了一个非常类似的问题

您当前的解决方案将是一个很好的答案

您可以有多个带有多个
fn
的curried参数,例如:

val rec member : ''a -> ''a list -> bool =
    fn x => fn [] => false
             | y::ys => x = y orelse member x ys
或者你可以像现在这样做,或者像马特建议的那样:

local
  fun member _ [] = false
    | member x (y::ys) = x = y orelse member x ys
in
  val member = member : ''a -> ''a list -> bool
end
但是使用
fun
和首先列出完整的类型签名的组合仍然是难以捉摸的

对于类似于产品的代码,规范是在模块签名中收集类型签名。见:签名和摘要,第267-268页。虽然我想你会想用Ocaml