我正在研究一个包含monoid的applicative函数来“查看”执行。然而,有时候我根本不关心这个部分,所以幺半群的选择是不相关的,因为它永远不会被消耗。我已经简化我有什么到:使用约束类型和类型族具有“受限制”的约束
{-# 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
转换且为单一b
。 Merge
是我的实际仿函数的一个很大的简化,但重点是它包含一个类型族/约束,我的目的是明确指定什么Render
和Merge
需要。现在
,我可能要“跑”的Merge
,但丢弃的观点,这是类似于这样的:
runFoo :: Merge a => a -> Int
runFoo x = case merge x of() -> 5
但因为这将失败:
无法推断
(Renderer a())
从使用merge
我选择()
我的幺因为˚F产生或者a
,我们有一个Render a()
的实例。所以如果有一种方法可以说Merge a
只是意味着收集Render
约束,那么这将工作正常。当然,Merge a
比这更一般 - 它可以添加任意约束,这就解释了编译错误。
有没有办法实现我想要的没有更改runFoo
的签名?
是否'Renderer'总是正好包括一个'Render'? – 2013-01-04 13:55:21
@Tinctorius - 不,通常取决于'Foo'字段中不同类型的数量 – ocharles
'Merge'没有'b'作为参数吗? –