Functional programming Ocaml中的高阶类型构造函数和函子

Functional programming Ocaml中的高阶类型构造函数和函子,functional-programming,ocaml,Functional Programming,Ocaml,可以使用以下多态函数吗 let id x = x;; let compose f g x = f (g x);; let rec fix f = f (fix f);; (*laziness aside*) 是否为类型/类型构造函数或模块/函子编写?我试过了 type 'x id = Id of 'x;; type 'f 'g 'x compose = Compose of ('f ('g 'x));; type 'f fix = Fix of ('f (Fix 'f));; 对于类

可以使用以下多态函数吗

let id x = x;;
let compose f g x = f (g x);;
let rec fix f = f (fix f);;     (*laziness aside*)
是否为类型/类型构造函数或模块/函子编写?我试过了

type 'x id = Id of 'x;;
type 'f 'g 'x compose = Compose of ('f ('g 'x));;
type 'f fix = Fix of ('f (Fix 'f));;
对于类型,但它不起作用

以下是针对类型的Haskell版本:

data Id x = Id x
data Compose f g x = Compose (f (g x))
data Fix f = Fix (f (Fix f))

-- examples:
l = Compose [Just 'a'] :: Compose [] Maybe Char

type Natural = Fix Maybe   -- natural numbers are fixpoint of Maybe
n = Fix (Just (Fix (Just (Fix Nothing)))) :: Natural   -- n is 2

-- up to isomorphism composition of identity and f is f:
iso :: Compose Id f x -> f x
iso (Compose (Id a)) = a

Haskell允许更高类型的类型变量。ML方言(包括Caml)只允许“*”类型的类型变量。翻译成通俗易懂的英语

  • 在Haskell中,类型变量
    g
    可以对应于“类型构造函数”,如
    可能
    IO
    或列表。因此,如果Haskell示例中的
    gx
    Maybe
    并且
    x
    Integer
    ,那么
    gx
    就可以了

  • 在ML中,类型变量
    'g
    只能对应于
    int
    string
    等“基本类型”,而不能对应于
    option
    list
    等类型构造函数。因此,试图将一个类型变量应用于另一个类型是不正确的

据我所知,ML中的这种限制没有深刻的原因。最可能的解释是历史偶然性。当米尔纳最初提出关于多态性的想法时,他使用的是非常简单的类型变量,仅代表单一类型*。Haskell的早期版本也做了同样的事情,后来Mark Jones发现推断类型变量的种类实际上相当容易。Haskell很快被修改为允许更高类型的类型变量,但ML从未跟上


INRIA的人对ML做了很多其他的改变,我有点惊讶他们从来没有做过这个。当我用ML编程时,我可能会喜欢使用更高级的类型变量。但是它们不在那里,我不知道如何对您所说的示例进行编码,除非使用。

您可以在OCaml中执行类似的操作,使用模块代替类型,使用函子(高阶模块)代替高阶类型。但是它看起来更难看,并且没有类型推断能力,所以您必须手动指定很多内容

module type Type = sig
  type t
end

module Char = struct
  type t = char
end

module List (X:Type) = struct
  type t = X.t list
end

module Maybe (X:Type) = struct
  type t = X.t option
end

(* In the following, I decided to omit the redundant
   single constructors "Id of ...", "Compose of ...", since
   they don't help in OCaml since we can't use inference *)

module Id (X:Type) = X

module Compose
  (F:functor(Z:Type)->Type)
  (G:functor(Y:Type)->Type)
  (X:Type) = F(G(X))

let l : Compose(List)(Maybe)(Char).t = [Some 'a']

module Example2 (F:functor(Y:Type)->Type) (X:Type) = struct
  (* unlike types, "free" module variables are not allowed,
     so we have to put it inside another functor in order
     to scope F and X *)
  let iso (a:Compose(Id)(F)(X).t) : F(X).t = a
end

嗯。。。我不是高阶类型专家,也不是Haskell编程专家。 但这对于F#(即OCaml)来说似乎还可以,您可以使用这些工具吗:

type 'x id = Id of 'x;;
type 'f fix = Fix of ('f fix -> 'f);;
type ('f,'g,'x) compose = Compose of ('f ->'g -> 'x);;

最后一个我打包成了tuple,因为我没有找到更好的…

你可以做,但你需要做点小动作:

newtype Fix f = In{out:: f (Fix f)}
您可以在以后定义Cata:

Cata :: (Functor f) => (f a -> a) -> Fix f -> a
Cata f = f.(fmap (cata f)).out
这将为所有函子定义一个通用的反同构,您可以使用它来构建自己的东西。例如:

data ListFix a b = Nil | Cons a b
data List a = Fix (ListFix a)
instance functor (ListFix a) where
fmap f Nil = Nil
fmap f (Cons a lst) = Cons a (f lst)

我“我不是100%确定,因为我不认识哈斯克尔,也不清楚f g x=。。。实际上是指Haskell,但您可能有兴趣知道OCAML的开发版本有一流的模块。我很确定您不能在ML中这样做,因为您需要更高级的多态性。你能给出一些在Haskell中如何使用这些类型的例子吗!(链接是我相信的)Chris Conway,我添加了一些示例。但是,我的意思是像
(list,option,int)compose
,这相当于
(int option)list
。我认为这可以通过使用选项类型来实现。在F#中,您也可以以.NET方式使用多个类型参数:type compose'g->'x);;但这可能不是真正的OCaml语法。问题是关于OCaml的函子(不同于Haskell的函子)。对不起,我误解了这个问题。无论如何,希望这能帮助任何接触过它的人。Ocaml于1996年首次发布,当时let多态性限制是确保完整类型推断和主要类型的一种简单方法。我不知道你所说的“相当容易”是什么意思,但秩-2多态性的类型重建只在中发现。当然,对于等级3和更高的等级是不可判定的(同上)。@Huitseek:问题不在于等级2类型(在Haskell中为所有量词嵌套
),而在于高阶类型(嵌套
->
),第1.1节讨论了轻量级高级多态性的别名问题。在Scala的DOT中对HKT的(抽象类型)模型进行细化,也包括推理问题。抽象依赖类型。请添加与问题的修复类型构造函数相对应的模块。