我可以显式地将类型类字典传递给函数吗?

Ale*_*ing 6 haskell typeclass ghc

假设我有一些类型类:

data Foo = Foo deriving (Show)

class Monad m => MonadFoo m where
  getFoo :: m Foo
Run Code Online (Sandbox Code Playgroud)

由于GHC通过字典传递(SPECIALIZE尽管使用了)来实现类型类,因此它有效地转换getFoo为类似下面的内容:

data MonadFooDict m = MonadFooDict { getFoo :: m Foo }
Run Code Online (Sandbox Code Playgroud)

...并且在调用开头时插入一个额外的参数来getFoo围绕字典.

有时,我可能想要动态选择一个实例,因此自己传递一个字典可能是可取的.我可以通过创建一个将为我编写字典的实例来自己模拟这个.

newtype DynamicMonadFoo a = DynamicMonadFoo
    { runFoo :: MonadFooDict DynamicMonadFoo -> a }
  deriving ( Functor, Applicative, Monad
           , MonadReader (MonadFooDict DynamicMonadFoo) )

instance MonadFoo DynamicMonadFoo where
  getFoo = join $ asks _getFoo
Run Code Online (Sandbox Code Playgroud)

现在,给定一些带MonadFoo约束的runFoo函数,我可以使用该函数向它传递一个显式的类型类字典:

showCurrentFoo :: MonadFoo m => m String
showCurrentFoo = do
  foo <- getFoo
  return ("current foo: " ++ show foo)

ghci> runFoo showCurrentFoo MonadFooDict { _getFoo = return Foo }
"current foo: Foo"
Run Code Online (Sandbox Code Playgroud)

这真的很酷,但似乎这样一个简单的任务,GHC可能会在没有所有样板的情况下暴露某种类型的库(理想情况下,这种方式可以更好地处理非monadic类型类).鉴于GHC具有一些"反射式"功能Data.Typeable,这似乎不属于可能性范围,但我不确定它是否确实以某种形式存在.

任何现有的内置插件或其他库是否允许更自动地执行此操作?

Eri*_*ikR 6

在哈斯克尔学院有一篇关于此的文章:

反映类型和背面的价值

请参阅标题为动态构建类型类实例的结尾部分,但是手动字典呢?

  • StackOverflow不鼓励仅链接答案.请在此处添加有趣的内容. (6认同)
  • 另外,我应该提一下,我发现阅读[功能珍珠:隐式配置](http://okmij.org/ftp/Haskell/tr-15-04.pdf),启发反射包的论文,非常平易近人,有助于在更高层次上挖掘概念而不是筛选核心输出. (2认同)