约束与实例中的声明匹配-MonoLocalBinds

时间:2019-04-11 13:52:02

标签: haskell

该代码旨在采用简单的类型类,从而(在这一点上)对类型之间的功能关系进行建模。

> {-# LANGUAGE MultiParamTypeClasses #-}
> {-# LANGUAGE ScopedTypeVariables #-}
> {-# LANGUAGE AllowAmbiguousTypes #-}
> {-# LANGUAGE FlexibleInstances #-}
> {-# LANGUAGE FlexibleContexts #-}
> {-# LANGUAGE FunctionalDependencies #-}

> class Foo a b | a -> b where
>     foo :: a -> b
>     
> class Bar a b | a -> b where
>     bar :: a -> b

> data A a = A a
> data B b = B b

> instance Foo (A a) a where
>   foo (A a) = a

> instance Bar (B b) b where
>   bar (B b) = b

> f :: (Bar bar b, Foo foo bar) => foo -> b
> f x = bar (foo x)

> --g :: String
> g = f (A (B "1"))

想象一下,您有很多这类类型类,您想组成,但是如果您明确指定类型,则不想指定每一个,您需要简写或别名

也许可以将这些类型类组合成新的类型类,以便将其中一个公理类修改为自动类型,并自动传递给派生类。

> class (Foo foo bar,Bar bar a) => FooThenBar foo bar a where

您可以定义

> f' :: (FooThenBar foo bar b) => foo -> b
> f' x = bar (foo x)

但是你不能走

> f' x = bar (foo x)
> g' = f' (A (B "1"))

由于(A(B“ 1”))的类型,不存在FooThenBar ...

因此您创建了一个实例...

> instance (Bar bar b, Foo foo bar) => FooThenBar foo bar b

GHC抱怨

• The constraint ‘FooThenBar foo bar b’
    matches an instance declaration
  instance (Bar bar b, Foo foo bar) => FooThenBar foo bar b
    -- Defined at catdog.lhs:37:12
  This makes type inference for inner bindings fragile;
    either use MonoLocalBinds, or simplify it using the instance
• In the type signature: f' :: (FooThenBar foo bar b) => foo -> b

好吧...您将MonoLocalBinds放入...

> {-# LANGUAGE MonoLocalBinds #-}

它可以工作...但是有一些警报响起...我显然是在逻辑上说...

FooThenBar a b c <=>(Foo a b,Bar b c)

有问题吗?...我可能想创建很多这样的东西,感觉好像在滥用系统,而Ghc暗示这可能会在以后引起问题?

1 个答案:

答案 0 :(得分:1)

我认为您只是在要求约束同义词?

{-# LANGUAGE ConstraintKinds #-}

type FooThenBar foo bar b = (Foo foo bar, Bar bar b)

f' :: (FooThenBar foo bar b) => foo -> b
f' x = bar (foo x)

g' = f' (A (B "1"))  -- "1"