Ocaml 中是否有单个案例变体的用例?

如何解决Ocaml 中是否有单个案例变体的用例?

我一直在阅读 F# 文章,他们使用单个案例变体来创建不同的不兼容类型。但是在 Ocaml 中,我可以使用私有模块类型或抽象类型来创建不同的类型。在 Ocaml 中使用 F# 或 Haskell 等单例变体是否很常见?

解决方法

单个构造函数变体的另一个特殊用例是使用 GADT(和存在量化)擦除一些类型信息。 例如,在

type showable = Show: 'a * ('a -> string) -> showable
let show (Show (x,f)) = f x
let showables = [ Show (0,string_of_int); Show("string",Fun.id) ]

构造函数 Show 将给定类型的元素与打印函数配对,然后忘记元素的具体类型。这使得拥有一个 showable 元素列表成为可能,即使每个元素具有不同的具体类型。

,

就其价值而言,在我看来,这在过去的 OCaml 中并不特别常见。

我自己一直不愿意这样做,因为它总是要付出一些代价:type t = T of int 的表示总是大于 int 的表示。

但是最近(可能几年)可以将类型声明为未装箱,这消除了这个障碍:

type [@unboxed] t = T of int

因此,我个人最近更频繁地使用单构造函数类型。有很多优点。对我来说,主要的是我可以有一个不同的类型,它独立于它的表示是否恰好与另一种类型相同。

你当然可以用模块来达到这个效果,就像你说的。但这是一个相当繁重的解决方案。

(所有这些自然只是我的意见。)

,

单构造函数类型的另一种情况(尽管它与您最初创建不同类型的问题不太匹配):花哨的记录。 (与其他答案相比,这与其说是基本功能,不如说是一种语法上的便利。)

实际上,使用允许使用记录语法(包括可变字段!)编写构造函数参数的 relatively recent feature(在 2016 年随 OCaml 4.03 引入),您可以使用构造函数名称作为常规记录的前缀,Coq 风格.

type t = MakeT of {
  mutable x : int ;
  mutable y : string ;
}

let some_t = MakeT { x = 4 ; y = "tea" }
(* val some_t : t = MakeT {x = 4; y = "tea"} *)

它在运行时不会改变任何东西(就像 Constr (a,b) 具有与 (a,b) 相同的表示,前提是 Constr 是其类型的唯一构造函数)。构造函数使代码对人眼更加明确,它还提供了消除字段名称歧义所需的类型信息,从而避免了对类型注释的需要。它在功能上类似于通常的模块技巧,但更系统。

模式的工作原理是一样的:

let (MakeT { x ; y }) = some_t
(* val x : int = 4 *)
(* val y : string = "tea" *)

您还可以访问“包含”记录(无需运行时成本)、读取和修改其字段。然而,这个包含的记录不是一流的值:您无法存储它、将其传递给函数或返回它。

let (MakeT fields) = some_t in fields.x (* returns 4 *)
let (MakeT fields) = some_t in fields.x <- 42
(* some_t is now MakeT {x = 42; y = "tea"} *)

let (MakeT fields) = some_t in fields
(*                             ^^^^^^
   Error: This form is not allowed as the type of the inlined record could escape. *)

,

单构造函数(多态)变体的另一个用例是向函数的调用者记录一些东西。例如,您的函数返回的值可能有一个警告:

val create : unit -> [ `Must_call_close of t ]

使用变体强制您的函数调用者在其代码中对该变体进行模式匹配:

let (`Must_call_close t) = create () in (* ... *)

这使得他们更有可能关注变体中的消息,而不是可能被遗漏的 .mli 文件中的文档。

对于这个用例,多态变体更容易使用,因为您不需要为变体定义中间类型。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-
参考1 参考2 解决方案 # 点击安装源 协议选择 http:// 路径填写 mirrors.aliyun.com/centos/8.3.2011/BaseOS/x86_64/os URL类型 软件库URL 其他路径 # 版本 7 mirrors.aliyun.com/centos/7/os/x86
报错1 [root@slave1 data_mocker]# kafka-console-consumer.sh --bootstrap-server slave1:9092 --topic topic_db [2023-12-19 18:31:12,770] WARN [Consumer clie
错误1 # 重写数据 hive (edu)&gt; insert overwrite table dwd_trade_cart_add_inc &gt; select data.id, &gt; data.user_id, &gt; data.course_id, &gt; date_format(
错误1 hive (edu)&gt; insert into huanhuan values(1,&#39;haoge&#39;); Query ID = root_20240110071417_fe1517ad-3607-41f4-bdcf-d00b98ac443e Total jobs = 1
报错1:执行到如下就不执行了,没有显示Successfully registered new MBean. [root@slave1 bin]# /usr/local/software/flume-1.9.0/bin/flume-ng agent -n a1 -c /usr/local/softwa
虚拟及没有启动任何服务器查看jps会显示jps,如果没有显示任何东西 [root@slave2 ~]# jps 9647 Jps 解决方案 # 进入/tmp查看 [root@slave1 dfs]# cd /tmp [root@slave1 tmp]# ll 总用量 48 drwxr-xr-x. 2
报错1 hive&gt; show databases; OK Failed with exception java.io.IOException:java.lang.RuntimeException: Error in configuring object Time taken: 0.474 se
报错1 [root@localhost ~]# vim -bash: vim: 未找到命令 安装vim yum -y install vim* # 查看是否安装成功 [root@hadoop01 hadoop]# rpm -qa |grep vim vim-X11-7.4.629-8.el7_9.x
修改hadoop配置 vi /usr/local/software/hadoop-2.9.2/etc/hadoop/yarn-site.xml # 添加如下 &lt;configuration&gt; &lt;property&gt; &lt;name&gt;yarn.nodemanager.res