在论文Streams à la carte: Extensible Pipelines with
Object Algebras
中,Biboudis等人。概述一种模拟类型构造函数多态性的方法"使用对象代数。
我正在尝试使用此方法在F#中实现更高级的示例,类似于Typed Tagless Final Interpreters
中描述的示例,并具有以下内容:
type App<'f,'a> = interface end
type ExprSYM<'f,'a> =
abstract litInt: int -> App<'f,int>
abstract litBool : bool -> App<'f,bool>
abstract add : App<'f,int> -> App<'f,int> -> App<'f,int>
abstract gt : App<'f,int> -> App<'f,int> -> App<'f,bool>
abstract conj : App<'f,bool> -> App<'f,bool> -> App<'f,bool>
与Brand Freshness
相关的部分描述了在类型构造函数中嵌套类。我对F#的翻译如下:
type Eval<'a> =
static member t = new obj()
static member prj (app : App<Eval.t,'a>) = app :> Eval<'a>
inherit App<Eval.t,'a>
但是,我收到错误The type 't' is not defined
。
在F#中写这个的正确方法是什么?
答案 0 :(得分:2)
使用嵌套类并不特别为你买东西;正如作者所说
在OCaml的Yallop和White技术中,这在语法上通过品牌
CREATE DEFINER=`root`@`localhost` PROCEDURE `dodajKorisnikaProvjera`( IN p_ime varchar(15), IN p_prezime varchar(15), IN p_broj_telefona int, IN p_datum_rodjenja date, IN p_broj_vozacke int, IN p_grad_id int ) BEGIN if TIMESTAMPDIFF(year,p_datum_rodjenja,CURDATE()) >=18 then INSERT into korisnik( ime, prezime, broj_telefona, datum_rodjenja, broj_vozacke, grad_id) VALUES( p_ime, p_prezime, p_broj_telefona, p_datum_rodjenja, p_broj_vozacke, p_grad_id ); else select'Korisnik mora imati vise od 18 godina.'; end if; END
的“新鲜度”得到了保证,它是类型构造函数的私有。在Java中,按惯例确保属性:t
的每个子类型S
都有一个本地定义的品牌App
,除了t
之外不存在App<S.t, X>
的子类型
所以你可以用F#中的不同约定获得相同的结果(它不支持嵌套类或接口中的静态成员)。例如,您可以在模块中创建子类以及单独的标记类:
S
然后确保您不在其他地方使用module Pull =
type t = class end
type Pull<'t> =
inherit App<t, 't>
let prj (app : App<t, 't>) = app :?> Pull<'t>
。