1

Background: I'm working with wxHaskell's fileOpenDialog, which takes 6 non-obvious parameters (curried). My code is currently:

maybePath <- fileOpenDialog w useLastSelectedDir canSelectReadOnly
                frameName possibleFiles initialDir defaultFilename

with a let statement above that to define all my parameters. What I would love to do though, is save my parameters somewhere. I somewhat understand why Haskell would't support something like say:

myParams = ( ... ) -- tuple of params
maybePath <- fileOpenDialog myParams

However, is there something close to this in the spirit of not repeating myself?

sepp2k
  • 363,768
  • 54
  • 674
  • 675
allidoiswin
  • 2,543
  • 1
  • 20
  • 23

2 Answers2

2

It seems like you would naturally like the input to this function to be a record of parameters:

{-# LANGUAGE RecordWildCards #-} 

-- Defined by your library 
foo :: String -> Int -> IO () 
foo = ... 

data Opts = Opts { optString :: String, optInt :: Int } 
bar :: Opts -> IO () 
bar Opts{..} = foo optString optInt 

Now, you can use any of the following equivalent syntaxes (some use RecordWildCards):

main = do 
  let optString = <...>
      optInt    = <...>
  bar Opts{..} 

main = do 
  let x = <...>
      y = <...>
      myParams = Opts x y 
  bar myParams 

main = do 
  bar $ Opts 
    { optString = <...> 
    , optInt    = <...> 
    } 

main = do 
  let optString = <...>
      optInt    = <...>
      myParams  = Opts{..} 
  bar myParams 
user2407038
  • 14,400
  • 3
  • 29
  • 42
  • This still requires me to define my parameters in main. I would like to define my parameters once, forever, outside of main, so I can call foo with those parameters anywhere, perhaps with something like `bar foo myOpts`. – allidoiswin Dec 06 '15 at 04:27
  • 1
    You can absolutely define your parameters as a top level value which you may use from anywhere. I see absolutely no reason that `myParams` must be a local definition inside of main - I just happened to give 4 examples where it was the case. You then call your function with `bar myParams`, just the same as above. – user2407038 Dec 06 '15 at 17:19
  • Oops. Brainfart. Apparently we can use NamedFieldPuns to pattern-match record fields easier: https://twitter.com/haskelltips/status/432255638849064960 – allidoiswin Dec 07 '15 at 02:38
1

There is also the (less clean) possibility of writing an uncurry variant (see here) having more arguments:

uncurry6 :: (a -> b -> c -> d -> e -> f -> g) -> ((a,b,c,d,e,f) -> g)
uncurry6 fun (a,b,c,d,e,f) = fun a b c d e f 

Having that, uncurry6 fileOpenDialog will make fileOpenDialog accept a 6-tuple.

user3389669
  • 799
  • 6
  • 20