ocaml任何类型匹配 [英] ocaml any types matching

查看:92
本文介绍了ocaml任何类型匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个函数,该函数可以选择以函数作为参数

I'm trying to write a function that optionally take a function as argument

let xxx ?(extractor = (fun a -> a)) yyy = ...

这最终将具有以下类型:

This ends up having type:

val xxx: ?extractor:('a -> 'a) -> 'c -> ...

我的目的是让提取器成为从结构中提取信息的函数,因此返回类型可以是任何东西,但我希望默认值为标识函数

My intention is to have the extractor to be a function that extract information from a structure, so the return type can be anything, but I want the default to be identity function

我试图将其在mli中的签名更改为

I tried to change the signature of it in the mli as

val xxx: ?extractor:('a -> 'b) -> 'c -> ...

但是它不能编译,表示('a->'a)与(a'->'b)不兼容.我感到奇怪的是('a->'a)不是(a'->'b)的子集.我可以在mli文件中输入一个语法('a-> *)吗?

But it does not compile, saying that ('a -> 'a) is not compatible with (a' -> 'b). I find it strange that ('a -> 'a) is not subset of (a' -> 'b). Is there a syntax that I can put in the mli file to say ('a -> *) ?

推荐答案

在函数式语言中,您从函数返回的未指定(变量)类型基本上必须出现在您传入的类型中.否则,在哪里价值将来自何处?因此,没有'a -> 'b.

In a functional language, an unspecified (variable) type you get back from a function basically has to appear somewhere in the type that you pass in. Otherwise, where would the value come from? So there are no (useful) functions of type 'a -> 'b.

考虑期望传递给函数的类型,以及提取函数与它们之间的关系可能会有所帮助.应该有一个相当直接的关系.与类型系统进行斗争通常意味着您要尝试做可能会意外失败的事情,而这正是类型系统要防止的事情.

It might help to think about the types that you're expecting to pass to your function, and how the extractor function would relate to them. It should be possible to have a fairly straightforward relation. Fighting with the type system usually means you're trying to do something that is likely to fail unexpectedly, which is what the type system is trying to prevent.

也许我要说的是提取器函数的输入和输出类型'a'b不会是任意类型.输入类型'a可能以某种方式与类型'c相关.类似地,结果类型'b可能将与整个函数xxx的返回类型相关.没有有关这些关系的更多信息,很难提出建议.

Maybe what I'm trying to say is that 'a and 'b, the input and output types of your extractor function, aren't going to be arbitrary types. The input type 'a is probably related somehow to the type 'c. Similarly the result type 'b is probably going to be related to the return type of the function xxx as a whole. Without a little more info about these relationships, it's hard to make suggestions.

如果您尝试将它们视为独立的任意类型,则会遇到上面我所说的参数不可能. (它也需要高级输入,我认为是2级多态性.)

If you try to think of them as independent, arbitrary types you run into the parametric impossibility that I was talking about above. (It also requires advanced typing, rank 2 polymorphism I think it is.)

作为一个简单的例子,假设'a'c是相同的类型,而'b是该函数的返回类型.然后,您的函数几乎必须像这样:

As a simple example, say that 'a and 'c are the same type and that 'b is the return type of the function. Then your function would pretty much have to look like this:

let xxx ?extractor s =
    match extractor with
    | Some f -> f s
    | None -> s

这具有您想要的行为:默认提取器功能是identity函数.但这也迫使f的返回类型与其输入类型相同.所以xxx的类型是:

This has the behavior you wanted: the default extractor function is the identity function. But this also forces the return type of f to be the same as its input type. So the type of xxx is:

val xxx : ?extractor:('a -> 'a) -> 'a -> 'a

除非您想变得非常花哨,否则实际上是无法解决的,我怀疑一个花哨的解决方案会带来复杂性,而复杂性将超过拥有可选参数的便利性.

Unless you want to get extremely fancy, there's really no way around this, and I suspect a fancy solution would introduce complexities that would outweigh the convenience of having the optional parameter.

也许具有两个功能会起作用.要继续简化的示例,它们将如下所示:

Maybe it would work to have two functions. To continue the simplified example they would look like this:

# let xxx extractor s = extractor s;;
val xxx : ('a -> 'b) -> 'a -> 'b = <fun>
# let xxx_id s = xxx (fun x -> x) s;;
val xxx_id : 'a -> 'a = <fun>

我认为这些类型具有您想要的类型,唯一的不便是您有两个不同的名称.

I think these have the types you want, and the only inconvenience is that you have two different names.

这篇关于ocaml任何类型匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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