2017-01-10 47 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)'。 –

相關問題