所以我有一个必须具有某种类型的函数。我的实现类似于以下内容:
f :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int
f t1 t2 t3 t4 t5 t6 t7 t8 t9
= filterFirst checkFunc p
where
p = findAll [1..9]
checkFunc = validate t1 t2 t3 t4 t5 t6 t7 t8 t9
现在我有什么办法可以缩写t值以更改验证然后重新排列f 或类似以下内容:
f :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int
f ts
= filterFirst checkFunc p
where
p = findAll [1..9]
checkFunc = validate ts
一种使外观看起来更干净的方法将是惊人的。
修改:更多详细信息
validate :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> [Int] -> Bool
validate t1 t2 t3 t4 t5 t6 t7 t8 t9 is =
[t1, t2, t3, t4, t5, t6, t7, t8, t9] == sums is
-- Calculates sums from specific indexes in list
sums :: [Int] -> [Int]
-- from https://stackoverflow.com/a/28904773/1218369
filterFirst :: (a -> Bool) -> [a] -> [a]
-- Find all possible permutations
findAll :: [a] -> [[a]]
-- Basically Data.List (permutations)
问题是f必须将值作为参数传递。我一直在寻找,甚至某些可以接受任意数量的参数并生成列表的函数也会很有帮助,但是我似乎找不到任何具有这种功能的模块。
答案 0 :(得分:1)
首先,让我们以一种看起来更像是将filterFirst
的部分应用程序与实际上消耗t
值的函数组成的形式来重写它:
f t1 t2 t3 t4 t5 t6 t7 t8 t9 = let cf = validate t1 t2 t3 t4 t5 t6 t7 t8 t9
in (flip filterFirst) (findAll [1..9]) cf
http://pointfree.io然后告诉我们以上等同于
f = ((((((((flip filterFirst (findAll [1..9]) .) .) .) .) .) .) .) .) . validate
多层构成使我们避免在定义中重复使用t
名称。
但是,我不会声称这是对显式版本的改进。