F# 编写F“要解析的代码”;2+;2“;编码

F# 编写F“要解析的代码”;2+;2“;编码,f#,F#,昨天刚开始,对F#来说是新的 我想要的是:编写代码,将字符串“2+2”解析为(使用教程项目中的示例代码)Expr.Add(Expr.Num 2,Expr.Num 2)进行计算。有些人至少可以帮我指出正确的方向,或者告诉我这对我的第一个F#项目来说太复杂了。(这就是我学习东西的方式:用头撞硬的东西) 我所拥有的:我对提取数字的代码的最佳猜测。可能离基地太远了。而且,缺乏线索 let script = "2 + 2"; let rec scriptParse xs = match xs w

昨天刚开始,对F#来说是新的

我想要的是:编写代码,将字符串“2+2”解析为(使用教程项目中的示例代码)Expr.Add(Expr.Num 2,Expr.Num 2)进行计算。有些人至少可以帮我指出正确的方向,或者告诉我这对我的第一个F#项目来说太复杂了。(这就是我学习东西的方式:用头撞硬的东西)

我所拥有的:我对提取数字的代码的最佳猜测。可能离基地太远了。而且,缺乏线索

let script = "2 + 2";

let rec scriptParse xs =
    match xs with
    | [] -> (double)0
    | y::ys -> (double)y

let split = (script.Split([|' '|]))
let f x = (split[x]) // "This code is not a function and cannot be applied."
let list = [ for x in 0..script.Length -> f x ]

let result = scriptParse 

谢谢。

您遇到的直接问题是
split
是一个字符串数组。要访问此数组的元素,语法是
split.[x]
,而不是
split[x]
(假设它是一个函数,它将
split
应用于单例列表
[x]

以下是一些其他问题:

  • 您对
    列表
    的定义可能是错误的:
    x
    的范围是
    脚本
    的长度,而不是数组的长度
    拆分
    。如果要将数组或其他序列转换为列表,可以使用
    list.ofSeq
    Seq.toList
    而不是显式的列表理解
    […]
  • 您对double的“强制转换”有点奇怪-这不是在F#中执行转换的正确语法,尽管在这种情况下它可以工作
    double
    是一个函数,因此括号是不必要的,您所做的实际上是调用
    double 0
    double y
    。对于第一种情况,您应该只使用
    0.0
    ,而对于第二种情况,您不清楚转换的是什么

  • 一般来说,最好先做一点设计来决定您的总体策略是什么,因为我不清楚您是否能够根据当前的方法拼凑出一个有效的解析器。编写解析器有几种众所周知的技术—您是否尝试使用特定的方法?

    什么是
    Expr.Num
    ?你知道如何用你已经知道的语言来解决这个问题吗?我强烈地考虑使用F-β幂包并使用它。从头开始写这篇文章很难;琼斯,在我看来,这是一个学习练习,而不是一个真正的项目。所以,使用库可能不是最好的解决方案。@svick-我建议使用合适的工具,而不是一个可以做到这一点的神奇库。词汇分析器使这变得容易得多;但这并不是一个神奇的挥手动作。如果这是一个F#学习练习,那么知道F#拥有强大的语法支持是一个好主意。我会看看Jon Harrop的这篇优秀博文:我对脚本的知识仅限于几篇文章,没有书籍。然而,我已经为C#编写了一种原始的、可扩展的脚本语言(尽管只供我自己使用),所以我并不是完全没有准备的。这也不是我计划“立即”完成的事情;这更像是一个最终目标,我可以对F#说“好吧,我学会了这个,那个和其他”。与此同时,我写了一个“猜我的号码”游戏。但是,我确实使用了三个可变项: