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平等!为什么它给我一个冲突?(另外,关于如何制作多变量 mconcat 的任何提示(以printf图书馆的风格)?

4

1 回答 1

3

您可以通过更改第二个实例声明并添加以下内容来编译并执行您想要的操作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 只查看实例的头部以确定它是否满足覆盖条件,但您可以(几乎)始终通过进行此转换来实现相同的实例。它甚至可以处理多态情况!

>: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]
于 2016-01-22T04:17:11.990 回答