我正在研究一个包含一个用于“查看”执行的幺半群的应用函子。然而,有时我根本不关心这部分,所以幺半群的选择是无关紧要的,因为它永远不会被消耗。我已经简化了我所拥有的:
{-# 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
Render
用于将各种a
s 转换为单个b
. Merge
是我实际仿函数的一个很大的简化,但关键是它包含一个类型族/约束,我的意图是准确指定Render
ers a 的Merge
要求。
现在,我可能想“运行” Merge
,但丢弃视图,类似于:
runFoo :: Merge a => a -> Int
runFoo x = case merge x of () -> 5
但这会失败,因为:
无法推断出
(Renderer a ())
使用merge
我选择()
作为我的幺半群a
,因为我们有一个Render a ()
. 因此,如果有办法说这Merge a
仅意味着集合Render
约束,那么这将正常工作。当然,Merge a
比这更笼统 - 它可以添加任意约束,这解释了编译错误。
有没有在不改变签名的情况下实现我想要的runFoo
?