2015-09-25 87 views
1

我正在解决一些关于在Haskell中生成祖先实例的方法。最近我在Haskell wiki上发现了这个:Class system extension proposal。所以,我想知道,这个提案有没有解决方案?Haskell:类系统扩展建议

以下是该建议的例子:

Haskell中当前类系统是基于这个想法,你可以 经常在同一 时间提供默认的实现类方法的定义通过使用该类的其他方法或其祖先。然而考虑以下层次结构,改编自 函子层次的建议,另一个前奏:在回报和方面

class Functor m where 
    fmap :: (a -> b) -> m a -> m b 

class Functor m => Applicative m where 
    return :: a -> m a 

    apply :: m (a -> b) -> m a -> m b 

    (>>) :: m a -> m b -> m b 
    ma >> mb = (fmap (const id) ma) `apply` mb 

class Applicative m => Monad m where 
    (>>=) :: m a -> (a -> m b) -> m b 

因为我们可以定义FMAP,申请单子的所有具体实例, (>>)(> > =),如下所示:

fmap f ma = ma >>= (\a -> return (f a)) 

apply mf ma = mf >>= \f -> ma >>= \a -> return (f a) 

ma >> mb = ma >>= \_ -> mb 

换句话说,我们希望能写:

class Applicative m => Monad m where 
    (>>=) :: m a -> (a -> m b) -> m b 

    fmap f ma = ma >>= (\a -> return (f a)) 

    apply mf ma = mf >>= \f -> ma >>= \a -> return (f a) 

    ma >> mb = ma >>= \_ -> mb 

和能够定义新的实例单子的只有我通过写作由回归和(>> =)提供 定义:

这是必要的,这样大的程序可以不用担心 建成实例

instance Monad T where 
    ma >>= a_mb = ... -- some definition 

    return a = ... -- some definition 

明确的导入/导出在不同的包之间冲突实例声明。一个可能的 语法是:

module M 
    -- exported instances 
    (instance Monad T 
    , instance Functor (F a) hiding (Functor (F Int), Functor (F Char)) 
    , F(..) 
    ) where 

import Foo (instance Monad a hiding Monad Maybe) 

data T a 
data F a b 

文意会被省略,因为这不是在实例 选择使用(目前)。 import指令告诉编译器 使用由Foo导出的所有Monad实例,除了Monad Maybe 实例(无论Foo实际上是否导出了一个 Monad Maybe实例都无关紧要 - 这里所有重要的是我们不需要'如果有的话,我想要它 )。

+4

您应该将链接中的相关部分复制到的问题,这样的问题是稳健linkrot。 –

回答

3

是的,DefaultSignatures扩展名允许这样做。例如,对于Functor/Applicative例如,你可以写

{-# LANGUAGE DefaultSignatures #-} 
class Functor f where 
    fmap :: (a -> b) -> f a -> f b 
    default fmap :: Applicative f => (a -> b) -> f a -> f b 
    fmap = liftA 
+1

这是一个糟糕的扩展。比没有好,是的,但它是非常有限的,它需要超类知道子类,它真的只是倒过来。 – dfeuer