该代码旨在采用简单的类型类,从而(在这一点上)对类型之间的功能关系进行建模。
> {-# 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暗示这可能会在以后引起问题?
答案 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"