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
或可能
或列表。因此,如果Haskell示例中的IO
是gx
并且Maybe
是x
,那么Integer
就可以了gx
- 在ML中,类型变量
只能对应于'g
或int
等“基本类型”,而不能对应于string
或option
等类型构造函数。因此,试图将一个类型变量应用于另一个类型是不正确的list
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的(抽象类型)模型进行细化,也包括推理问题。抽象依赖类型。请添加与问题的修复类型构造函数相对应的模块。