0

So I have a function which has to have a certain type. My implementation is similar to the following:

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

Now is there any way I could abbreviate the t values to either change validate and then rearrange f or something similar the following:

f :: Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int -> Int
f ts
    = filterFirst checkFunc p
    where
        p = findAll [1..9]
        checkFunc = validate ts

A way to make this look cleaner would be amazing.

Edit: More Detail

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)

The problem is f must have the values passed as parameters. I was looking and even some function that takes any number of parameters and produces a list would be helpful but I can't seem to find any module with such function.

luke
  • 1,005
  • 7
  • 19
  • Please provide a [mcve](https://stackoverflow.com/help/mcve) of the code you want to simplify. – typetetris Oct 19 '18 at 19:43
  • 3
    The isomorphism you want between `Int -> ... Int -> Int` and `(Int, ..., Int) -> Int` isn't going to be any prettier than what you are doing now. Somewhere along the line, a bad design decision lead to you needing `f` to have that type. – chepner Oct 19 '18 at 20:04
  • That's what I was thinking. I didn't make the design decision for `f` but have to work with it. Was just hoping there was a way to select all the arguments like in other languages or formulate a function using validate which I could use to make a definition for f without specifying the arguments. – luke Oct 19 '18 at 20:09

1 Answers1

1

First, let's rewrite this in a form that looks closer to composing a partial application of filterFirst with a function that actually consumes the t values:

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 then tells us that the above is equivalent to

f = ((((((((flip filterFirst (findAll [1..9]) .) .) .) .) .) .) .) .) . validate

The multiple layers of composition allows us to avoid repeating the t names in the definition.

I wouldn't, however, claim this is an improvement over your explicit version.

chepner
  • 497,756
  • 71
  • 530
  • 681