2017-01-10 46 views
1

它看起来好像转换应该形成一个Monoid,其中标识函数为空元素,标准函数组合为二元运算。我认为这不是特别有用,但它应该是可能的。沿着线的东西:转换集f :: a->一个形式在函数组合上的幺半群 - 我该如何使这是一个Monoid的实例?

instance Monoid (a -> a) where 
     mempty = id 
     mappend f g = (.) 

以上不编译,可能是因为它是由预先存在的定义屏蔽

instance Monoid b => Monoid (a -> b) where 
    mempty _ = mempty 
    mappend f g x = f x `mappend` g x 

错误是:

Illegal instance declaration for ‘Monoid (a -> a)’ 
     (All instance types must be of the form (T a1 ... an) 
     where a1 ... an are *distinct type variables*, 
     and each type variable appears at most once in the instance head. 
     Use FlexibleInstances if you want to disable this.) 
    In the instance declaration for ‘Monoid (a -> a)’ 

我米仍然是一个Haskell擦洗,所以我不知道我怎么能解决这个问题 - 任何帮助?

+2

作为脚注中重复的答案,一个漂亮的使用'Endo'在[得到一个默认实现为'foldr'出'foldMap'](的一个例子http://stackoverflow.com/q /2751851分之23319683)。 – duplode

回答

2

实际上错误消息描述它很好:a -> a是太具体类型:

所有实例类型必须是以下形式(T a1 ... an) 其中a1 ... an不同类型变量, 和每种类型的可变在实例头中最多出现一次。

这里的T是函数型->,你也许能写没有特别的中间符号

instance Monoid ((->) a a) where … 

,并明确a并不只出现一次。

关于如何可以解决此问题,再次错误信息建议

使用FlexibleInstances如果要禁用此[限制。

+1

或者使用'TypeFamilies'并写'instance a〜b => Monoid(a - > b)'。 –

相关问题