简体   繁体   中英

Given a function g :: a -> b -> … -> z, how can I use it like h :: (a, b, …) -> z?

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?

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 

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM