Haskell将多个参数缩写为一个变量

时间:2018-10-19 19:34:04

标签: haskell functional-programming currying

所以我有一个必须具有某种类型的函数。我的实现类似于以下内容:

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必须将值作为参数传递。我一直在寻找,甚至某些可以接受任意数量的参数并生成列表的函数也会很有帮助,但是我似乎找不到任何具有这种功能的模块。

1 个答案:

答案 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名称。

但是,我不会声称这是对显式版本的改进。