当我在ghci中编译我的代码时,没有问题.它可以正确编译.但是,如果我尝试在拥抱中编译它,我会收到错误"编译代码太复杂".我认为问题是由于许多|条件造成的.
如果我将其更改为使用if/else,则没有问题.我可以添加if/else语句100次,但这将非常烦人和恼人.而不是那样,我试图在20-30 |条件之后放置if/else语句,但是|如果语句如下所示我无法进行工作:
f x y z
| cond1 = e1
| cond2 = e2
...
if (1)
then
| cond30 = e30
| cond31 = e31
...
else
| cond61 = e61
| cond62 = e62
Run Code Online (Sandbox Code Playgroud)
如何以最少的努力修复代码?完整的代码在hpaste上,因为它比StackOverflow的问题大小限制更长.
首先,你可以重写
function input
| this && that && third thing && something else = ... -- you only actually needed brackets for (head xs)
| this && that && third thing && something different = ....
| this && that && a change && ...
...
| notthis && ....
Run Code Online (Sandbox Code Playgroud)
同
function input | this = function2 input'
| notthis = function4 input'
function2 input | that = function3 input''
| notthat = ...
Run Code Online (Sandbox Code Playgroud)
这应该简化你的200行copo代码,但它仍然是错误的方法.
处理您经常处理的操作的4个案例可以用一个函数替换,可能如下:
operation :: Num a => Char -> a -> a -> a
operation x = case x of
'+' -> (+)
'-' -> (-)
'*' -> (*)
'/' -> (/)
_ -> error ("operation: expected an operation (+-*/) but got " ++ [c])
Run Code Online (Sandbox Code Playgroud)
您应该使用一些标准函数来帮助减少所有单个字符检查,只需抓取尽可能多的数字.takeWhile :: (a -> Bool) -> [a] -> [a]所以
takeWhile isDigit "354*243" = "354"
takeWhile isDigit "+245" = ""
Run Code Online (Sandbox Code Playgroud)
并且有相应的dropWhile:
dropWhile isDigit "354*1111" = "*1111"
dropWhile isDigit "*1111" = "*1111"
Run Code Online (Sandbox Code Playgroud)
所以最明显的缩短代码就是开始代码
copo xs = let
numText = takeWhile isDigit xs
theRest = droWhile isDigit xs
num = read numText
....
in answer....
Run Code Online (Sandbox Code Playgroud)
但有一个快捷键,如果你想既takeWhile和dropWhile,叫span,因为span p xs == (takeWhile p xs, dropWhile p xs)
copo xs = let
(numText,theRest) = span isDigit xs
num = read numText
....
in answer....
Run Code Online (Sandbox Code Playgroud)
你处理234,然后234*56再234*56/23然后....
您可以使用递归调用替换它copo,或生成树.这取决于您是否应该遵守正常的运算符优先级(*或/在+或 - 之前).
| 归档时间: |
|
| 查看次数: |
190 次 |
| 最近记录: |