[英]“could not deduce … from the context …”, despite context holding what's necessary
The following file fails to compile: 以下文件无法编译:
{-# 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
It gives the errors: 它给出了错误:
[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.
It seems to me that I'm giving the right context, but I don't know how to convince GHC of this. 在我看来,我提供的是正确的环境,但是我不知道该如何说服GHC。
Related files: 相关文件:
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 = (->)
This error occurs because when you call mid ()
, it has the type Monoid () p0 (->) m => i -> m
, and there is nothing constraining p0
to be the particular p
you chose since p0
does not appear on the right hand side of the =>
sign in the type signature. 发生此错误的原因是,当您调用
mid ()
,其类型为Monoid () p0 (->) m => i -> m
,并且没有将p0
限制为您选择的特定p
,因为p0
不会出现在类型签名中=>
符号的右侧。 One way to work around this is through the FunctionalDependencies
extension: 解决此问题的一种方法是通过
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
However, this won't work for append
, as the variable i
now has to be constrained. 但是,这不适用于
append
,因为变量i
现在必须受到约束。 This just means that we need to have it dependent on our choice for m
as well: 这只是意味着我们也需要使它也取决于我们对
m
的选择:
class Category c => Monoid i p c m | m -> i, m -> p where
-- ...
And now it'll compile. 现在它将编译。 Whether or not this is what you want to do, I don't know, but I do know that it'll get your code compiling.
我不知道这是否是您要执行的操作,但我确实知道这将使您的代码得到编译。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.