在F#中printf有格式说明符%A,它可以传入任何F#类型,并且它将被评估和打印.
举个例子:
type Result<'a> =
| Failure
| Success of 'a
printf "%A" (Success "hello") // prints out 'Success "hello"'
Run Code Online (Sandbox Code Playgroud)
显然,Result<'a>它不是内置类型.
我可以在OCaml中声明一个类似的类型,但是没有等效的说明符Printf.printf- 相反,我必须实现我自己的string_of_result函数,并使用%s格式字符串中的说明符.此外,由于这是一个多态类型,我将不得不创建一个可以处理任何类型实例的非直接函数'a.
我的问题是 - 为什么OCaml缺少这个方便的说明符?是因为没有动力实施它吗?是因为有一些缺乏引擎盖的魔力,这就是F#中的那个吗?
我想知道 F# 是如何实现的let rec,但我找不到答案。作为前言,我将介绍一下 Scheme 是如何实现的letrec:
let只是lambda定义和应用的语法糖:(let ((x 1)) (+ x 2))
变换为
((lambda (x) (+ x 2)) 1)
(在每种情况下,表达式的计算结果为3)。
letrec也是语法糖,但#f作为初始参数传递给 lambda 的参数,并且set!表达式在主体之前注入letrec,就像在这个转换中一样:(letrec ((x 1)) (+ x 2)) => ((lambda (x) (begin (set! x 1) (+ x 2))) #f)。
考虑到F#没有与Scheme等效的运算符set!,它是如何实现的let rec?它是否将函数的参数声明为mutable,然后在函数体内对它们进行变异?
作为一种消遣,我正在尝试解决我在大学学习的课程(涉及 Lambda 微积分和各种编程概念)中提出的各种问题。因此,我尝试在 OCaml 中实现 Church 数字和相关运算符(也作为 OCaml 中的练习)。
这是到目前为止的代码:
let church_to_int n =
n (fun x -> x + 1) 0;;
let succ n s z =
s (n s z)
let zero = fun s z -> z
let int_to_church i =
let rec compounder i cont =
match i with
| 0 -> cont zero
| _ -> compounder (i - 1) (fun res -> cont (succ res))
in
compounder i (fun x -> x)
let add …Run Code Online (Sandbox Code Playgroud) 我开始学习Scala的兴趣,我决定将Scott Wlaschin的解析器组合包从F#翻译成Scala,所以这些东西真的会解决.Scott的包的全部意思是几乎到处都使用monad,所以我我也认为这是一个进一步理解单子的机会.
在其中一张早期幻灯片中,他定义了类型type Parser<'a> = Parser of (string -> Result<'a * string>),其中:
type Result<'a> =
| Success of 'a
| Failure of string
Run Code Online (Sandbox Code Playgroud)
这个定义中的微妙之处在于'a方程两边的耦合Parser<'a>.
在任何情况下,我如何将上述语句翻译成Scala,同时保留我提到的微妙之处?
对于第一个,我想到了这个:
type ParserType[T] = String => Result[(T, String)]
Run Code Online (Sandbox Code Playgroud)
而对于第二个(这是一种选择类型)我想到了这个:
sealed trait Result[T]
case class Success[T](result: T) extends Result[T]
case class Failure[T](msg: String) extends Result[T]
Run Code Online (Sandbox Code Playgroud)
但是,似乎愚蠢的使用[T]中Failure,因为它不使用T在所有.是否有一些语法可以更接近F#语法?