简体   繁体   English

尽管上下文认为有必要,但“无法根据上下文推论……”

[英]“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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM