在构建语言时是否应该区别对待变量和字符串?
Should variables and strings be treated differently in constructing a language?
我目前正在研究一种语言,遇到了一个关于变量声明的问题,为了检查变量在 REPL 中的值,我必须使用引号。
> x := 1
> "x"
1
然而,所需的行为如下:
> x := 1
> x
1
我按以下方式定义了我的 ADT:
data S = Integer Integer | String String | Assign String S | Expr Add [S]
我可以正确解析所有内容。
parseString :: Parser HVal
parseString = char '"' *> many1 (noneOf "\"") <* char '"' >>= (return . String)
parseAssign :: Parser HVal
parseAssign = do
var <- many1 letter
spaces
string ":="
spaces
val <- try (parsersHVal)
spaces
return $ Assign var val
不过我认为问题出在评估函数上。
evalHVal :: Env -> HVal -> IOThrowsError HVal
evalHVal env val@(Integer _) = return $ val
evalHVal env val@(String _) = return $ val
evalHVal env (String val) = getVar env val >>= \var -> evalHVal env var
如果我保留计算字符串的第一行,REPL 中会出现以下情况,并且我会收到第二行多余的警告:
> x := 1
> "x"
'x'
如果我保留第二行,我会得到从一开始就描述的行为。
在这两种情况下,都必须在变量周围加上引号才能对其进行评估。我意识到我在函数 parseAssign
中使用 many1 letter
而不是 parseString
。我尝试将其更改为 parseString
但我得到了相同的行为。
然而,最让我困惑的是,既然所有内容都是作为字符串读入的,那么为什么 many1 letter
不需要像 parseString
那样在 parseAssign
中使用引号?我尝试将 parseString
更改为以下内容 (many1 letter >>= (return . String)
),但它既不分配也不允许像以前那样使用字符串。
变量和字符串应该被区别对待。尽管它们在源语言中都是字符串,但它们不能被等同对待,因为它们在语言的数据模型中是不同的。
Should variables and strings be treated differently in constructing a language?
是
data S = ...
应该是:
data S = ... | Var String
What confuses me the most however is that since everything is read in as a string, then why doesn't many1 letter require quotations in parseAssign like how parseString requires?
这应该是显而易见的。见定义:
parseString = char '"' *> ...
parseString 的第一部分显然看起来是在解析 char '"'
。
parseAssign 的定义没有寻找"
.
I tried changing parseString to the following (many1 letter >>= (return . String)) but it neither assigns nor allows for the use of strings like before.
嗯,"
不是 letter
,所以它不应该't/wouldn 允许使用引号。此外,它不会“分配”,无论动词是什么意思,因为它缺少 Assign
构造函数以及 parseAssign
.
的所有其他关键部分
我目前正在研究一种语言,遇到了一个关于变量声明的问题,为了检查变量在 REPL 中的值,我必须使用引号。
> x := 1
> "x"
1
然而,所需的行为如下:
> x := 1
> x
1
我按以下方式定义了我的 ADT:
data S = Integer Integer | String String | Assign String S | Expr Add [S]
我可以正确解析所有内容。
parseString :: Parser HVal
parseString = char '"' *> many1 (noneOf "\"") <* char '"' >>= (return . String)
parseAssign :: Parser HVal
parseAssign = do
var <- many1 letter
spaces
string ":="
spaces
val <- try (parsersHVal)
spaces
return $ Assign var val
不过我认为问题出在评估函数上。
evalHVal :: Env -> HVal -> IOThrowsError HVal
evalHVal env val@(Integer _) = return $ val
evalHVal env val@(String _) = return $ val
evalHVal env (String val) = getVar env val >>= \var -> evalHVal env var
如果我保留计算字符串的第一行,REPL 中会出现以下情况,并且我会收到第二行多余的警告:
> x := 1
> "x"
'x'
如果我保留第二行,我会得到从一开始就描述的行为。
在这两种情况下,都必须在变量周围加上引号才能对其进行评估。我意识到我在函数 parseAssign
中使用 many1 letter
而不是 parseString
。我尝试将其更改为 parseString
但我得到了相同的行为。
然而,最让我困惑的是,既然所有内容都是作为字符串读入的,那么为什么 many1 letter
不需要像 parseString
那样在 parseAssign
中使用引号?我尝试将 parseString
更改为以下内容 (many1 letter >>= (return . String)
),但它既不分配也不允许像以前那样使用字符串。
变量和字符串应该被区别对待。尽管它们在源语言中都是字符串,但它们不能被等同对待,因为它们在语言的数据模型中是不同的。
Should variables and strings be treated differently in constructing a language?
是
data S = ...
应该是:
data S = ... | Var String
What confuses me the most however is that since everything is read in as a string, then why doesn't many1 letter require quotations in parseAssign like how parseString requires?
这应该是显而易见的。见定义:
parseString = char '"' *> ...
parseString 的第一部分显然看起来是在解析 char '"'
。
parseAssign 的定义没有寻找"
.
I tried changing parseString to the following (many1 letter >>= (return . String)) but it neither assigns nor allows for the use of strings like before.
嗯,"
不是 letter
,所以它不应该't/wouldn 允许使用引号。此外,它不会“分配”,无论动词是什么意思,因为它缺少 Assign
构造函数以及 parseAssign
.