简体   繁体   中英

Can some explain the reflection package API in *very* simple terms?

I'm having a hard time understanding the documentation/examples out there describing the reflection package. I'm an imperative-programming veteran but a Haskell newb. Can you walk me through a very simple introduction?

Package: https://hackage.haskell.org/package/reflection

Edit: to whoever closed this question: this is meant to be a beginner introduction to Haskell reflection. The answer below is excellent and others would be useful too, so please reopen.

In the simplest use-case, if you have some configuration information you'd like to make generally available across a set of functions:

data Config = Config { w :: Int, s :: String }

you can add a Given Config constraint to the functions that need access to the configuration:

timesW :: (Given Config) => Int -> Int

and then use the value given to refer to the current configuration (and so w given or s given to refer to its fields):

timesW x = w given * x

With a few other functions, some that use the configuration and some that don't:

copies :: Int -> String -> String
copies n str = concat (replicate n str)

foo :: (Given Config) => Int -> String
foo n = copies (timesW n) (s given)

you can then run a computation under different configurations that you give :

main = do
  print $ give (Config 5 "x") $ foo 3
  print $ give (Config 2 "no") $ foo 4

This is similar to:

  • defining given :: Config globally, except you can run the computation under multiple configurations in the same program;

  • passing the configuration around as an extra parameter to every function, except you avoid the bother of explicitly accepting the configuration and passing it on, like:

     timesW cfg x = w cfg * x foo cfg n = copies (timesW cfg n) (s cfg)
  • using a Reader monad, but you don't have to lift everything to an awkward monad- or applicative-level syntax, like:

     timesW x = (*) <$> asks w <*> pure x foo n = copies <$> timesW n <*> asks s

The full example:

{-# LANGUAGE FlexibleContexts #-}

import Data.Reflection

data Config = Config { w :: Int, s :: String }

timesW :: (Given Config) => Int -> Int
timesW x = w given * x

copies :: Int -> String -> String
copies n str = concat (replicate n str)

foo :: (Given Config) => Int -> String
foo n = copies (timesW n) (s given)

main = do
  print $ give (Config 5 "x") $ foo 3
  print $ give (Config 2 "no") $ foo 4

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