以下文件无法编译:
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
module AltMonad.Monoid where
import AltMonad.Category
import Prelude (curry)
class Category c
=> Monoid i p c m where
mid :: i `c` m
mcomb :: (m `p` m) `c` m
class Monoid () (,) (->) m
=> HaskellMonoid m where
empty :: m
append :: m -> m -> m
instance Monoid () (,) (->) m
=> HaskellMonoid m where
empty = mid ()
append = curry mcomb
它给出了错误:
[3 of 3] Compiling AltMonad.Monoid ( AltMonad\Monoid.hs, interpreted )
AltMonad\Monoid.hs:24:12:
Could not deduce (Monoid () p0 (->) m)
arising from a use of `mid'
from the context (Monoid () (,) (->) m)
bound by the instance declaration
at AltMonad\Monoid.hs:(22,10)-(23,24)
The type variable `p0' is ambiguous
Relevant bindings include
empty :: m (bound at AltMonad\Monoid.hs:24:3)
In the expression: mid ()
In an equation for `empty': empty = mid ()
In the instance declaration for `HaskellMonoid m'
AltMonad\Monoid.hs:25:18:
Could not deduce (Monoid i0 (,) (->) m)
arising from a use of `mcomb'
from the context (Monoid () (,) (->) m)
bound by the instance declaration
at AltMonad\Monoid.hs:(22,10)-(23,24)
The type variable `i0' is ambiguous
Relevant bindings include
append :: m -> m -> m (bound at AltMonad\Monoid.hs:25:3)
In the first argument of `curry', namely `mcomb'
In the expression: curry mcomb
In an equation for `append': append = curry mcomb
Failed, modules loaded: AltMonad.Category, AltMonad.Hask.
在我看来,我给出了正确的背景,但我不知道如何说服GHC。
相关文件:
AltMonad.Category
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeSynonymInstances #-}
module AltMonad.Category where
import AltMonad.Hask
class Category cat where
id :: cat a a
(.) :: b `cat` c -> a `cat` b -> a `cat` c
instance Category Hask where
id = \x -> x
g . f = \x -> g (f x)
AltMonad.Hask
{-# LANGUAGE NoImplicitPrelude #-}
module AltMonad.Hask where
type Hask = (->)
答案 0 :(得分:2)
发生此错误是因为当您致电mid ()
时,它的类型为Monoid () p0 (->) m => i -> m
,并且没有任何约束p0
成为您选择的特定p
p0
=>
1}}不会出现在类型签名中FunctionalDependencies
符号的右侧。解决此问题的一种方法是通过-- ...
class Category c => Monoid i p c m | m -> p where
mid :: c i m
mcomb :: c (p m m) m
-- ...
instance Monoid () (,) (->) m => HaskellMonoid m where
empty = mid ()
append = curry mcomb
扩展程序:
append
但是,这不适用于i
,因为现在必须约束变量m
。这只是意味着我们需要依赖于我们对class Category c => Monoid i p c m | m -> i, m -> p where
-- ...
的选择:
{{1}}
现在它会编译。不管这是不是你想要做的,我不知道,但我知道它会让你的代码编译。