我可以注释"fun"声明的完整类型吗? [英] Can I annotate the complete type of a `fun` declaration?

查看:79
本文介绍了我可以注释"fun"声明的完整类型吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在学习环境中,为功能提供类型签名的我有哪些选择?

In a learning environment, what are my options to provide type signatures for functions?

标准ML没有像Haskell这样的顶级类型签名.这是我考虑过的替代方案:

Standard ML doesn't have top-level type signatures like Haskell. Here are the alternatives I have considered:

  1. 模块签名,它需要一个单独的签名文件,或者在与模块本身相同的文件中的一个单独的块中定义的类型签名.这要求使用模块,并且在任何生产系统中都应该使用模块.

  1. Module signatures, which require either a separate signature file, or the type signature being defined in a separate block inside the same file as the module itself. This requires the use of modules, and in any production system that would be a sane choice.

当替代方案是单个函数定义时,模块在存根文件中似乎有些冗长.他们都介绍了模块的概念,也许还为时过早.

Modules may seem a little verbose in a stub file when the alternative is a single function definition. They both introduce the concept of modules, perhaps a bit early,

使用valval rec我可以在一行中包含完整的类型签名:

Using val and val rec I can have the complete type signature in one line:

val incr : int -> int =
  fn i => i + 1

val rec map : ('a -> 'b) -> 'a list -> 'b list =
  fn f => fn xs => case xs of
       []    => []
     | x::ys => f x :: map f ys

我可以同时使用fun吗?

Can I have this and also use fun?

如果可能的话,我似乎无法正确理解语法.

If this is possible, I can't seem to get the syntax right.

当前的解决方案是像这样嵌入参数类型和结果类型:

Currently the solution is to embed the argument types and the result type as such:

fun map (f : 'a -> 'b) (xs : 'a list) : 'b list =
  raise Fail "'map' is not implemented"

但是我经历过,这种语法给ML新手以一种印象,即解决方案不能或不应该更新为模型解决方案:

But I have experienced that this syntax gives the novice ML programmer the impression that the solution either cannot or should not be updated to the model solution:

fun map f [] = []
  | map f (x::xs) = f x :: map f xs

然后,应该帮助学生的类型签名似乎阻止了它们的模式匹配.我不能说这是因为他们认为不能删除类型签名还是应该删除它们.当然,他们是否应该(以及在何处)是样式问题,但是应该使学生能够探索类型推断的样式.

It seems then that the type signatures, which are supposed to aid the student, prevents them from pattern matching. I cannot say if this is because they think that the type signatures cannot be removed or if they should not be removed. It is, of course, a matter of style whether they should (and where), but the student should be enabled to explore a style of type inference.

推荐答案

通过使用let或局部绑定函数以及阴影 您可以声明该函数,然后将其分配给一个值.

By using a let or local bound function, and shadowing you can declare the function, and then assign it to a value.

为此使用local更方便,因为它具有以下形式: decl 结尾的本地 decl ,而不是 expr 结尾的 decl 意思是让我们 expr 想要一个顶级参数 f

using local for this is more convenient, since it has the form: local decl in decl end, rather than let decl in expr end, meaning let's expr, wants a top-level argument f

val map = fn f => let fun map = ... in map end

我不相信人们通常使用 local ,这主要是因为模块可以完成local可以做的任何事情,甚至更多,但是当您不使用模块时,也许值得将其视为匿名模块还想解释模块.

I don't believe people generally use local, anymore primarily because modules can do anything that local can, and more, but perhaps it is worth considering it as an anonymous module, when you do not want to explain modules yet.

local
  fun map (f : 'a -> 'b) (x::rest : 'a list) : 'b list
        = f x :: map f rest
    | map _ ([]) = []

 in
 val (map : ('a -> 'b) -> 'a list -> 'b list) = map;
end

然后,当需要解释模块时,您可以在局部内部,所有声明周围声明结构, 然后删除本地变量,并尝试解决一种情况,即他们已经编码了2个函数,并且更合适的是用1种结构替换2个本地变量.

Then when it comes time to explain modules, you can declare the structure inside the local, around all of the declarations, and then remove the local, and try to come up with a situation, where they have coded 2 functions, and it's more appropriate to replace 2 locals, with 1 structure.

local
  structure X = struct
    fun id x = x
  end
  in val id = X.id 
end

也许用以下类似的东西开始它们:

perhaps starting them off with something like the following:

exception ReplaceSorryWithYourAnswer

fun sorry () = raise ReplaceSorryWithYourAnswer

local
  (* Please fill in the _'s with the arguments
     and the call to sorry() with your answer *)
  fun map _ _ = sorry ()
in
  val map : ('a -> 'b) -> ('a list) -> ('b list) = map
end

这篇关于我可以注释"fun"声明的完整类型吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆