functional-programming - 我可以注释 `fun` 声明的完整类型吗?

标签 functional-programming sml

在学习环境中,我有哪些选择来为函数提供类型签名?

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

  • 模块签名,需要单独的签名文件,或者类型签名在与模块本身相同的文件内的单独 block 中定义。这需要使用模块,并且在任何生产系统中都是明智的选择。

    当替代方案是单个函数定义时, stub 文件中的模块可能看起来有点冗长。他们都引入了模块的概念,也许有点早,
  • 使用 valval rec我可以在一行中获得完整的类型签名:
    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 ?

    如果这是可能的,我似乎无法正确使用语法。
  • 目前的解决方案是嵌入参数类型和结果类型:
    fun map (f : 'a -> 'b) (xs : 'a list) : 'b list =
      raise Fail "'map' is not implemented"
    

    但我体验过这种语法给新手 ML 程序员的印象是解决方案不能或不应该更新为模型解决方案:
    fun map f [] = []
      | map f (x::xs) = f x :: map f xs
    

    似乎应该帮助学生的类型签名阻止他们进行模式匹配。我不能说这是因为他们认为不能删除类型签名还是不应该删除它们。当然,他们是否应该(以及在哪里)是一个风格问题,但是应该让学生能够探索一种类型推断的风格。
  • 最佳答案

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

    使用 local 更方便,因为它具有以下形式:
    local decl in decl end,而不是 let decl in expr end,
    意思是让我们expr,想要一个顶级参数

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

    我不相信人们通常使用本地 , 主要是因为模块可以做任何本地可以做的事情,甚至更多,但是当你还不想解释模块时,也许值得将其视为匿名模块。
    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个局部更合适。
    local
      structure X = struct
        fun id x = x
      end
      in val id = X.id 
    end
    

    也许从以下内容开始:
    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
    

    关于functional-programming - 我可以注释 `fun` 声明的完整类型吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52874203/

    相关文章:

    exception-handling - 在 Clojure 中处理纯度错误?

    sml - 将命令行参数传递给 SML 脚本

    pattern-matching - 在EQUALOP发现SML语法错误

    emacs - 在 sml 中,为什么会产生错误 : syntax error: deleting IN IF

    haskell - Haskell 有什么大惊小怪的?

    haskell - 是否有在 GPU 上运行的函数式编程语言?

    PHP 与 array_filter 相反?

    scala - Tarjan 强连通分量算法的功能实现

    sml - 什么符号!在 SML 中是什么意思?

    sml - Cons 在这个函数中做了什么?