【问题标题】:Declaring type of function in SML在 SML 中声明函数的类型
【发布时间】:2019-03-04 18:14:31
【问题描述】:

我是 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 _ 必须出现在下面完全定义的函数,其中这对人类读者来说不太明显,除非您只是习惯这种模式并学会期待它。

【问题讨论】:

    标签: sml ml


    【解决方案1】:

    我最近问了一个非常相似的问题,Can I annotate the complete type of a fun declaration?

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

    您可以有多个带有多个 fn 的柯里化参数,例如喜欢:

    val rec member : ''a -> ''a list -> bool =
        fn x => fn [] => false
                 | y::ys => x = y orelse member x ys
    

    或者你可以像现在一样做,或者按照 matt 的建议:

    local
      fun member _ [] = false
        | member x (y::ys) = x = y orelse member x ys
    in
      val member = member : ''a -> ''a list -> bool
    end
    

    但是使用fun 和完整的类型签名首先列出的组合仍然难以捉摸。

    对于类似生产的代码,规范是在模块签名中收集类型签名。请参阅ML for the Working Programmer, ch. 7签名和抽象,第 267-268 页。虽然我想你会想要使用 Ocaml。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-02
      • 2021-04-11
      相关资源
      最近更新 更多