och*_*les 5 haskell type-families constraint-kinds
我正在开发一个包含monoid的应用程序仿函数来"查看"执行.然而,有时我根本不关心这一部分,因此选择monoid是无关紧要的,因为它永远不会被消耗掉.我简化了我的所作所为:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
import GHC.Exts
class Render a b where render :: a -> b
instance Render a () where render = const ()
class Merge a where
type Renderer a b :: Constraint
merge :: Renderer a b => a -> b
data Foo = Foo Bool
instance Merge Foo where
type (Renderer Foo) m = (Render Bool m)
merge (Foo b) = render b
Run Code Online (Sandbox Code Playgroud)
Render用于将各种as转换为单个b.Merge是我的实际仿函数的一个很大的简化,但关键是它包含一个类型族/约束,我的意图是准确指定所需的Renderers Merge.
现在,我可能想"运行" Merge,但丢弃视图,类似于:
runFoo :: Merge a => a -> Int
runFoo x = case merge x of () -> 5
Run Code Online (Sandbox Code Playgroud)
但这会失败,因为:
无法推断
(Renderer a ())使用merge
我选择()作为我的幺半群因为forall a,我们有一个实例Render a ().因此,如果有一种方式可以说Merge a只是意味着一个集合Render约束,那么这将工作正常.当然,Merge a比这更通用 - 它可以添加任意约束,这解释了编译错误.
反正有没有改变签名而实现我想要的东西runFoo?
如果你有很多这种情况,这可能无法扩展,但这有效:
class Renderer a () => Merge a where
...
Run Code Online (Sandbox Code Playgroud)