如何避免此Haskell命令中的重复x
ccheck :: Balance -> Integer
ccheck b | x >= 1200 = x - 7
| otherwise = x
where x = account b
答案 0 :(得分:6)
嗯,你可以做任何无点的事情。
import Control.Arrow
ccheck = uncurry (+) . (min 0 . (*7) . signum . (1199-) &&& id) . account
但是WTH。你的版本很好,它正在发生的事情更加清晰,正如上校三十二所说的那样,它根本不是重复的。
答案 1 :(得分:2)
如果您愿意,可以完全省略:
ccheck = ((+) <*> ((-7) *) . signum . (1+) . signum . (-1200 +)) . account
然而,这并不比条件情况更具可读性(特别是,为了避免使用if
语句我们正在使用signum . (1+) . signum
,这有点令人头疼;最右边的一个映射低于集合{-1,0,1}的整数和(1+)将其转换为{0,1,2},下一个signum再次减少为{0,1}。
答案 2 :(得分:2)
你可以使它的可读性低得多
ccheck = join (liftM2 if' (>= 1200) (subtract 7)) . account
where if' b l r = if b then l else r
答案 3 :(得分:2)
“改善”@bheklilr的答案:
import Control.Monad
import Data.Bool
ccheck = liftM3 bool id (subtract 7) (>= 1200) . account
另一个“无意义”风格的例子。
答案 4 :(得分:1)
我不认为代码是重复的,但不过这是我的看法。首先,介绍以下组合器:
cond p f g x = if p x then f x else g x
然后,将ccheck
定义为:
ccheck = cond (>= 1200) (subtract 7) id . account
答案 5 :(得分:0)
如果您想进行更多检查,请从头顶开始:
ccheck = chainConditions [((>=1200), subtract 7] id . account
chainConditions :: [(a -> Bool, a -> b)] -> (a -> b) -> a -> b
chainConditions [] g x = g x
chainConditions ((p,f):rest) g x =
| p x = f x
| otherwise = chainConditions rest g x
使用@Xavier Pinho的答案,这可能也可以表达为foldr (.) otherwiseFunction (map (uncurry cond) conditions)
,但这是一个疯狂的猜测!你可以把DRY推得太远; - )