具有参数类型的一流模块(类型构造函数F.f会逃避其范围)

编程入门 行业动态 更新时间:2024-10-25 04:20:40
本文介绍了具有参数类型的一流模块(类型构造函数F.f会逃避其范围)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我目前正在使用模块,以查看可以哪种方式将它们以类似于Haskell类型类的方式使用.目前,我正在尝试使用仿函数类型类:

I am currently playing around with modules, to see in which way they can be used in similar ways to Haskell type classes. Currently I am trying to play around with the functor type class:

module type Functor = sig type 'a f val fmap : ('a -> 'b) -> ('a f -> 'b f) end module IdFunc = struct type 'a f = Id of 'a let fmap f = fun (Id a) -> Id (f a) let runId (Id a) = a end let outmap (module F : Functor) av = F.fmap f av

但是,在这种情况下,outmap的键入将不正确,编译器会产生错误The type constructor F.f would escape its scope.我知道为什么在这种情况下会导致此错误,但是我不确定如何解决(因为类型f已参数化).

However in this case outmap will not be typed correctly, the compiler produces the error The type constructor F.f would escape its scope. I know why this error is caused in this case, but I am not sure how to work around it (because type f is parametrized).

我已经尝试使用本地抽象类型:

I already tried to use locally abstract types:

let outmap (type s) (module F : Functor with type 'a f = s) f av = F.fmap f av

let outmap (type a) (type b) (type fa) (type fb) (module F : Functor with type a f = fa type b f = fb) f av = F.fmap f av

let outmap (type s) (module F : Functor with type f = s) f av = F.fmap f av

这一切都给我各种语法错误或键入错误.

which all just give me various syntax errors or typing errors.

有什么办法可以解决这个问题?

Is there any way to work around this?

在Haskell中,这将是:

In Haskell this would just be:

outmap : Functor f => (a -> b) -> f a -> f b

ocaml(如果有的话)相当于什么?

what would be the equivalent in ocaml (if any)?

====编辑====

==== EDIT ====

我找到了一种获得与工作类似的东西的方法:

I found one way to get something similar to work:

module type Functor = sig type a type b type af type bf val fmap : (a -> b) -> (af -> bf) end module type FromTo = sig type a type b end module IdFunc = functor (FT : FromTo) -> struct type a = FT.a type b = FT.b type 'a f = Id of 'a type af = a f type bf = b f let fmap f = fun (Id a) -> Id (f a) let runId (Id a) = a end let outmap (type a') (type b') (type af') (type bf') (module F : Functor with type a = a' and type b = b' and type af = af' and type bf = bf') f av = F.fmap f av module M = IdFunc(struct type a = int type b = string end) let oi = outmap (module M) let test = oi (fun _ -> "Test") (M.Id 10)

但是对于某些可能应该更简单的事情来说,这似乎增加了很多复杂性.

But this looks like a lot of added complexity for something that should probably be much simpler.

推荐答案

恐怕您不能直接表达您要尝试做的事情,因为它是种类繁多的多态性(类型构造函数上的多态性)的一个示例,而并非支持OCaml的核心语言.

I'm afraid you cannot directly express what you are trying to do because it is an example of higher-kinded polymorphism (polymorphism over type constructors) which is not supported in OCaml's core language.

有关OCaml的核心语言为何不支持更高种类的多态性的解释,请参见轻巧的更高种类的1.1节多态性.

For an explanation of why OCaml's core language cannot support higher-kinded polymorphism see Section 1.1 in Lightweight higher-kinded polymorphism.

由于模块系统支持,因此解决此问题的常用方法是将outmap用作函子而不是函数.

Since the module system does support higher-kinded polymophism, the usual solution to this problem is to make outmap a functor rather than a function.

或者,上面链接的文章介绍了一种变通方法(在higher库中实现-在opam上可用),该变通方法实质上是在类型级别使用去功能化.是否比使用函子更方便取决于您的特定用例.

Alternatively, the paper linked above describes a workaround (implemented in the higher library -- available on opam) which essentially uses defunctionalisation at the type-level. Whether this is more convenient than using functors or not depends on your specific use cases.

更多推荐

具有参数类型的一流模块(类型构造函数F.f会逃避其范围)

本文发布于:2023-11-06 22:35:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1564860.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:类型   函数   模块   参数

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!