将 OCaml 代码转换为 F#
Transforming OCaml code to F#
我正在将一些 OCaml 代码转换为 F#,但 OCaml let...and...
存在问题,它仅通过使用递归函数存在于 F# 中。
我有给定的 OCaml 代码:
let matches s = let chars = explode s in fun c -> mem c chars
let space = matches " \t\n\r"
and punctuiation = matches "() [] {},"
and symbolic = matches "~'!@#$%^&*-+=|\:;<>.?/"
and numeric = matches "0123456789"
and alphanumeric = matches "abcdefghijklmopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ"
我想在这两种方法中使用:
let rec lexwhile prop inp = match inp with
c::cs when prop c -> let tok,rest = lexwhile prop cs in c+tok,rest
|_->"",inp
let rec lex inp =
match snd(lexwhile space inp)with
[]->[]
|c::cs ->let prop = if alphanumeric(c) then alphanumeric
else if symbolic(c) then symbolic
else fun c ->false in
let toktl,rest = lexwhile prop cs in
(c+toktl)::lex rest
有人知道我必须如何更改它才能使用它吗?
你可以只写:
let explode s = [for c in s -> string c]
let matches str strc =
let eStr = explode str
List.contains strc eStr
let space = matches " \t\n\r"
let punctuation = matches "() [] {},"
let symbolic = matches "~'!@#$%^&*-+=|\:;<>.?/"
let numeric = matches "0123456789"
let alphanumeric = matches "abcdefghijklmopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ"
F# 倾向于使用轻量级而非冗长的语法编写,因此您通常不需要使用 in
、begin
和 end
关键字。有关差异的详细信息,请参阅:https://msdn.microsoft.com/en-us/library/dd233199.aspx。
就个人而言,我可能会将所有这些 string -> bool
函数重构为活动模式,例如:
let (|Alphanumeric|_|) str =
match matches "abcdefghijklmopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ" str with
|true -> Some str
|false -> None
let (|Symbolic|_|) str =
match matches "~'!@#$%^&*-+=|\:;<>.?/" str with
|true -> Some str
|false -> None
然后就可以进行模式匹配了,例如:
match c with
|Alphanumeric _ -> // alphanumeric case
|Symbolic _ -> // symbolic case
|_ -> // other cases
您似乎在尝试翻译“Handbook of Practical Logic and Automated Reasoning”。
你看到了吗:An F# version of the book code 现已可用!感谢 Eric Taucher、Jack Pappas 和 Anh-Dung Phan。
你需要看看intro.fs
// pg. 17
// ------------------------------------------------------------------------- //
// Lexical analysis. //
// ------------------------------------------------------------------------- //
let matches s =
let chars =
explode s
fun c -> mem c chars
let space = matches " \t\n\r"
let punctuation = matches "()[]{},"
let symbolic = matches "~`!@#$%^&*-+=|\:;<>.?/"
let numeric = matches "0123456789"
let alphanumeric = matches "abcdefghijklmnopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let rec lexwhile prop inp =
match inp with
| c :: cs when prop c ->
let tok, rest = lexwhile prop cs
c + tok, rest
| _ -> "", inp
let rec lex inp =
match snd <| lexwhile space inp with
| [] -> []
| c :: cs ->
let prop =
if alphanumeric c then alphanumeric
else if symbolic c then symbolic
else fun c -> false
let toktl, rest = lexwhile prop cs
(c + toktl) :: lex rest
我在翻译的时候在这里问了很多questions,并在他们前面加了Converting OCaml to F#:
。如果您查看评论,您会看到我们三个人是如何开始这个项目的。
我正在将一些 OCaml 代码转换为 F#,但 OCaml let...and...
存在问题,它仅通过使用递归函数存在于 F# 中。
我有给定的 OCaml 代码:
let matches s = let chars = explode s in fun c -> mem c chars
let space = matches " \t\n\r"
and punctuiation = matches "() [] {},"
and symbolic = matches "~'!@#$%^&*-+=|\:;<>.?/"
and numeric = matches "0123456789"
and alphanumeric = matches "abcdefghijklmopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ"
我想在这两种方法中使用:
let rec lexwhile prop inp = match inp with
c::cs when prop c -> let tok,rest = lexwhile prop cs in c+tok,rest
|_->"",inp
let rec lex inp =
match snd(lexwhile space inp)with
[]->[]
|c::cs ->let prop = if alphanumeric(c) then alphanumeric
else if symbolic(c) then symbolic
else fun c ->false in
let toktl,rest = lexwhile prop cs in
(c+toktl)::lex rest
有人知道我必须如何更改它才能使用它吗?
你可以只写:
let explode s = [for c in s -> string c]
let matches str strc =
let eStr = explode str
List.contains strc eStr
let space = matches " \t\n\r"
let punctuation = matches "() [] {},"
let symbolic = matches "~'!@#$%^&*-+=|\:;<>.?/"
let numeric = matches "0123456789"
let alphanumeric = matches "abcdefghijklmopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ"
F# 倾向于使用轻量级而非冗长的语法编写,因此您通常不需要使用 in
、begin
和 end
关键字。有关差异的详细信息,请参阅:https://msdn.microsoft.com/en-us/library/dd233199.aspx。
就个人而言,我可能会将所有这些 string -> bool
函数重构为活动模式,例如:
let (|Alphanumeric|_|) str =
match matches "abcdefghijklmopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ" str with
|true -> Some str
|false -> None
let (|Symbolic|_|) str =
match matches "~'!@#$%^&*-+=|\:;<>.?/" str with
|true -> Some str
|false -> None
然后就可以进行模式匹配了,例如:
match c with
|Alphanumeric _ -> // alphanumeric case
|Symbolic _ -> // symbolic case
|_ -> // other cases
您似乎在尝试翻译“Handbook of Practical Logic and Automated Reasoning”。
你看到了吗:An F# version of the book code 现已可用!感谢 Eric Taucher、Jack Pappas 和 Anh-Dung Phan。
你需要看看intro.fs
// pg. 17
// ------------------------------------------------------------------------- //
// Lexical analysis. //
// ------------------------------------------------------------------------- //
let matches s =
let chars =
explode s
fun c -> mem c chars
let space = matches " \t\n\r"
let punctuation = matches "()[]{},"
let symbolic = matches "~`!@#$%^&*-+=|\:;<>.?/"
let numeric = matches "0123456789"
let alphanumeric = matches "abcdefghijklmnopqrstuvwxyz_'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
let rec lexwhile prop inp =
match inp with
| c :: cs when prop c ->
let tok, rest = lexwhile prop cs
c + tok, rest
| _ -> "", inp
let rec lex inp =
match snd <| lexwhile space inp with
| [] -> []
| c :: cs ->
let prop =
if alphanumeric c then alphanumeric
else if symbolic c then symbolic
else fun c -> false
let toktl, rest = lexwhile prop cs
(c + toktl) :: lex rest
我在翻译的时候在这里问了很多questions,并在他们前面加了Converting OCaml to F#:
。如果您查看评论,您会看到我们三个人是如何开始这个项目的。