函数的Haskell作用域
我正在尝试做一些将在“where”子句之后定义的输入函数作为输入函数并输出由它组成的字符串的操作。提到它会将“where”子句之后列出的函数范围限定为 writeOut 函数。我想带什么(它不起作用):
writeOut :: [Char] -> [Char]
writeOut x = x
where
number :: Char -> [Char]
number n = [n]
multiplication :: [Char] -> [Char] -> [Char]
multiplication a b = a++"*"++b
addition :: [Char] -> [Char] -> [Char]
addition a b = "("++a++"+"++b++")"
subtraction :: [Char] -> [Char] -> [Char]
subtraction a b = "("++a++"-"++b++")"
...
因此,例如,对于输入:
writeOut multiplication (addition (number '1') (subtraction (number '2') (number '3'))) (number '3')
会给我一个输出:
(1+(2-3))*3
当我删除 writeOut 函数并只保留 'where' 关键字之后的内容时,它工作正常,但我真的想在 'writeOut' 函数下“锁定它”。
你可能会问我为什么要这样做,因为我想要另一个函数来为我计算表达式:
writeOut multiplication (addition (number '1') (subtraction (number '2') (number '3'))) (number '3')
Output: (1+(2-3))*3
calc multiplication (addition (number '1') (subtraction (number '2') (number '3'))) (number '3')
Ouput: 0
以防万一你想看看什么是“正常”工作的:
number :: Char -> [Char]
number n = [n]
multiplication :: [Char] -> [Char] -> [Char]
multiplication a b = a++"*"++b
addition :: [Char] -> [Char] -> [Char]
addition a b = "("++a++"+"++b++")"
subtraction :: [Char] -> [Char] -> [Char]
subtraction a b = "("++a++"-"++b++")"
回答
您似乎正在尝试为该 DSL 实现 DSL 和评估器。而不是一组函数,定义一个数据类型,然后为该类型编写一个评估器。
data Expr = Number Int
| Mult Expr Expr
| Add Expr Expr
| Subtract Expr Expr
writeOut :: Expr -> String
writeOut (Number x) = show x
writeOut (Add x y) = "(" ++ writeOut x ++ " + " ++ writeOut y ++ ")"
writeOut (Subtract x y) = "(" ++ writeOut x ++ " - " ++ writeOut y ++ ")"
writeOut (Mult x y) = "(" ++ writeOut x ++ " * " ++ writeOut y ++ ")"
print $ writeOut (Mult (Add (Number 1) (Subtract (Number 2) (Number 3))) (Number 3)
我把它作为一个练习来消除最外面的括号。
作为奖励分配,定义一个不同的评估器,将表达式评估为单个Int,而不是显示它:
evaluate :: Expr -> Int
evaluate = undefined