有人能用非常简单的术语解释反射包API吗



我很难理解描述反射包的文档/示例。我是一个命令式编程的老手,但却是Haskell的新手。你能带我做一个简单的介绍吗?

包装:https://hackage.haskell.org/package/reflection

编辑:对于结束这个问题的人:这是对Haskell反思的入门介绍。下面的答案很好,其他答案也很有用,所以请重新打开。

在最简单的用例中,如果您有一些配置信息,您希望在一组函数中通用:

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

您可以向需要访问配置的函数添加Given Config约束:

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

然后使用值given来指代当前配置(因此w givens given来指代其字段(:

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)

然后,您可以在give:的不同配置下运行计算

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

这类似于:

  • 全局定义given :: Config,除非您可以在同一程序中运行多个配置下的计算;

  • 将配置作为一个额外的参数传递给每个函数,除非您避免了显式接受配置并将其传递的麻烦,例如:

    timesW cfg x = w cfg * x
    foo cfg n = copies (timesW cfg n) (s cfg)
    
  • 使用Readermonad,但您不必将所有内容提升到尴尬的monad或应用级别语法,如:

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

完整示例:

{-# 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

相关内容

  • 没有找到相关文章

最新更新