0

Так я напечатал это доПочему я получаю конфликт?

{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, FunctionalDependencies #-} 

import Data.Monoid 

class Monoid m => Mconcat m a | a -> m where 
    mcon :: m -> a 

instance Monoid m => Mconcat m m where 
    mcon m = m 

instance Mconcat m a => Mconcat m (m -> a) where 
    mcon m m' = mcon (m `mappend` m') 

и я получаю

[1 of 1] Compiling Main    (pad.hs, interpreted) 

pad.hs:8:10: 
    Functional dependencies conflict between instance declarations: 
     instance Monoid m => Mconcat m m -- Defined at pad.hs:8:10 
     instance Mconcat m a => Mconcat m (m -> a) 
     -- Defined at pad.hs:11:10 
Failed, modules loaded: none. 

Дело в том, хотя, m и m->a не могут быть равны! Почему это дает мне конфликт? ? (Кроме того, любые советы относительно того, как сделать polyvariadic mconcat (в стиле printf библиотеки)

+2

Заменить 'm -> a' for' m' в первом экземпляре. –

+0

@ReidBarton oh, duh. По какой-то причине я думал, что это не сломает. – PyRulez

+0

Вы можете сделать эту компиляцию и потенциально делать то, что хотите (хотя я не уверен, что это такое, я не совсем уверен), если вы измените второй экземпляр на экземпляр (Mconcat ma, o ~ (m -> a)) => Mconcat mo' - для этого требуется 'UndecidableInstances'. 'OverlappingInstances' или' OVERLAPS' для более поздних версий второго экземпляра. – user2407038

ответ

2

Вы можете сделать это компиляции и делать то, что вы хотите, изменяя второе объявление экземпляра и добавление UndecidableInstances:

{-# LANGUAGE UndecidableInstances #-} 
... 
instance {-# OVERLAPS #-} (Mconcat m a, o ~ (m -> a)) => Mconcat m o where 

или на более ранних версиях GHC это должно работать (непроверенные)

{-# LANGUAGE UndecidableInstances, OverlappingInstances #-} 
... 
instance (Mconcat m a, o ~ (m -> a)) => Mconcat m o where 

Это работает, потому что GHC смотрит только на голове экземпляра, чтобы определить, если она удовлетворяет coverage condition, но вы можете (Álmos t) всегда достигают одного и того же экземпляра, делая это преобразование. Он даже обрабатывает полиморфные случаи!

>:set +t 
>mcon [1] [2] [34,34,2,53] [34,23,43] 
[1,2,34,34,2,53,34,23,43] 
it :: Num t => [t] 
>mcon "a" "b" "c" "d" "e" 
"abcde" 
it :: [Char] 
+0

Держу пари, это сделало бы хорошее дополнение к html-библиотеке (так что вам не нужно злоупотреблять нотой' do'). – PyRulez

+0

Типовой вывод часто очень сильно борется с вариационными функциями, что часто делает их менее полезными на практике. Я удивлен, что в этом случае так хорошо. Это может быть новый механизм OverlappingInstances, который делает это ... но я не совсем понимаю его, поэтому не знаю. – user2407038

 Смежные вопросы

  • Нет связанных вопросов^_^