【问题标题】:Pattern-match empty Fifo.fifo in SML/NJSML/NJ 中的模式匹配空 Fifo.fifo
【发布时间】:2018-10-05 10:43:21
【问题描述】:

当我尝试写类似的东西时

fun test Fifo.empty = true
  | test _ = false`

我收到一条错误消息,内容为 Error: variable found where constructor is required: Fifo.empty。我对 SML/NJ 真的很陌生。原来它与Fifo.empty 是一个longId 有关,但我还没有想出如何解决这个问题,除了通过传递Fifo.isEmpty 作为参数来修补它,但这几乎不是一个解决方案......

【问题讨论】:

    标签: pattern-matching sml fifo smlnj


    【解决方案1】:

    当您检查 Fifo 模块时,

    - open Fifo;
    [autoloading]
    [library $SMLNJ-LIB/Util/smlnj-lib.cm is stable]
    [autoloading done]
    opening Fifo
      datatype 'a fifo = ...
      exception Dequeue
      val empty : 'a fifo
      (* and so on *)
    

    您可以看到Fifo.empty 是一个'a fifo 值。要了解它是如何制作的,

    - Fifo.empty;
    val it = Q {front=[],rear=[]} : 'a fifo
    

    不幸的是,'a fifoQ 数据类型构造函数被opaque 的模块隐藏(因此datatype 定义显示为“...”。当您定义数据类型时,它的构造函数(例如Q)同时成为值构造函数模式构造函数,但是当你使用这样的值构造函数声明像Fifo.empty这样的值时,它们也不会成为模式构造函数。

    我还没有想出如何解决这个问题,除了通过传递 Fifo.isEmpty 作为参数来修补它,但这几乎不是解决方案......

    我不确定您为什么需要传入Fifo.isEmpty 作为参数;你不能只在函数体中引用Fifo.isEmpty 吗?也许你没有解释这个问题的维度。

    以下内容如何:

    fun test queue = Fifo.isEmpty queue
    

    或者简单地说:

    val test = Fifo.isEmpty
    

    一般来说,如果您想传入一堆库函数作为参数,您可以考虑构建一个高阶模块(函子),将另一个模块作为参数。

    【讨论】:

    • 我真的只是想避免使用 if 语句检查我的队列是否为空,而宁愿让模式匹配为我做这件事。不过感谢您的回答!
    • 模式匹配是当您可以访问数据类型的构造函数时要走的路。但是,当数据类型是抽象的/隐藏在接口后面时,就不再可能了。在 Fifo 的情况下,这是因为它的内部表示是一个 dequeue(双端),但不应仅限于此选择;即,如果您开始对其进行模式匹配,则您正在创建特定于实现的依赖项。
    猜你喜欢
    • 2014-09-30
    • 2010-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-10
    • 1970-01-01
    • 2023-04-05
    • 2021-06-01
    相关资源
    最近更新 更多