GHCI与编译函数差异:负数输入编译报错的解决咨询
问题解决与解释
首先,先修正你代码里的冗余部分:tillDot函数里的case判断完全没必要,takeWhile (/= '.')本身就会处理空字符串的情况(返回空),而且case分支里的x会覆盖参数名,简化后的代码更简洁且功能一致:
testFront :: Float -> String testFront x = tillDot $ show $ abs x tillDot :: String -> String tillDot = takeWhile (/= '.')
你遇到的“负数输入需加括号”是Haskell的语法规则导致的——函数调用的优先级高于负号,直接写testFront -14.4会被解析成testFront - 14.4,也就是试图用testFront返回的字符串和14.4做减法,这当然会报错。
如果想避免手动加括号,有两种实用方式:
- 用
$运算符调整优先级:调用时写testFront $ -14.4,$会让右侧的-14.4先求值,再传给函数。 - 定义成中缀运算符:比如:
这样调用时直接写infixl 9 ? (?) :: Float -> String x ? = tillDot $ show $ abs x-14.4 ?即可,无需括号。
不过要说明的是:Haskell的语法规则是编译前的解析逻辑,函数代码本身没法直接改变调用时的语法要求。理解这个优先级规则后,用括号或者$是最直接的常规写法,没必要额外绕弯。
内容的提问来源于stack exchange,提问作者VulpesNix
相关产品推荐
相关产品推荐

