I'm transforming some OCaml code to F# having a problem with the OCaml let...and...
which only exists in F# by using a recursive function.
I have the given OCaml code:
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"
which I want to use in these two methods:
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
Has someone any idea how I have to change it that so that I can use it?
It looks like you are trying to translate "Handbook of Practical Logic and Automated Reasoning".
Did you see: An F# version of the book code is now available! Thanks to Eric Taucher, Jack Pappas and Anh-Dung Phan.
You need to look at 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
I asked many questions here while working on the translation and prefixed them with Converting OCaml to F#:
. If you look in the comments you will see how the three of us came to work on this project.
You can just write:
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# tends to be written using lightweight, rather than verbose, syntax so you don't generally need to use the in
, begin
and end
keywords. See: https://msdn.microsoft.com/en-us/library/dd233199.aspx for details about the differences.
Personally, I would probably refactor all of those string -> bool
functions into active patterns, e.g.:
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
Then you can pattern match, e.g.:
match c with
|Alphanumeric _ -> // alphanumeric case
|Symbolic _ -> // symbolic case
|_ -> // other cases
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With