GHC тип выводов горе - PullRequest
       27

GHC тип выводов горе

5 голосов
/ 16 февраля 2012

Вопрос .Есть ли способ заставить этот код работать без явной подписи типа?

Код .Во-первых, у меня есть практический, более приятный альтернативный класс MonadTrans, вдохновленный Data.Newtype.Это выглядит так:

{-# LANGUAGE FlexibleContexts, TypeFamilies #-}

module Alt.Control.Monad.Trans where

import Control.Monad

class (Monad ?, Monad (BaseMonad ?)) => MonadTrans (? :: * -> *) where
    type BaseMonad ? :: * -> *
    lift :: (BaseMonad ?) α -> ? α

Тогда у меня есть класс A с методом foo, и если какая-то базовая монада M является A, то любая преобразованная монада T Mтакже A.В коде

class A ? where
    foo :: String -> ? ()

instance (A (BaseMonad ?), MonadTrans ?) => A ? where
    foo n = lift $ foo n

Однако, если я теперь хочу создать ярлык для foo с заменой первого аргумента, тогда мне нужна явная сигнатура типа или переполнение стека контекста компилятора.

minimize_call :: A ? => ? ()
minimize_call = foo "minimize"

Возможная информация для помощи в выводе .Допустим, у нас есть связанный тип B :: * -> *.Я думаю, что хочу сказать, что компилятор B удовлетворяет B t /= t, B (B t) /= B t и т. Д. Т.е.знать, что он не может навсегда удалить оболочки нового типа, поэтому необходимо добавить контекст A к подписи.

1 Ответ

3 голосов
/ 16 февраля 2012

Да, есть способ.Предоставьте обоснованный экземпляр для A и добавьте NoMonomorphismRestriction к языковой прагме (в дополнение к обязательным FlexibleInstances и UndecidableInstances).

Однако класс Aбудет непригодным для использования. Компилятор не сможет узнать, что никогда не будет экземпляра MonadTrans с BaseMonad m = m.Таким образом, он никогда не может выбрать экземпляр, потому что он не может знать, использовать ли экземпляр здесь или другой.

{-# LANGUAGE FlexibleContexts, TypeFamilies, FlexibleInstances, UndecidableInstances, NoMonomorphismRestriction #-}

module Trans (MonadTrans(..), A(..), minimize_call) where

import Control.Monad

class (Monad m, Monad (BaseMonad m)) => MonadTrans (m :: * -> *) where
    type BaseMonad m :: * -> *
    lift :: (BaseMonad m) α -> m α

class A m where
    foo :: String -> m ()


data Foo a = Bork

instance Monad Foo where
    return _ = Bork
    _ >>= _ = Bork

instance A Foo where
    foo _ = Bork


instance (A (BaseMonad m), MonadTrans m) => A m where
    foo n = lift $ foo n

-- minimize_call :: A m => m ()
minimize_call = foo "minimize"

компилируется с ghc 6.12, 7.0, 7.2 и 7.4.Без подписи minimize_call должен получить мономорфный тип, если MR не выключен.Это не может работать в любом случае, потому что ограничение A m не является дефолтным.Поэтому MR должен быть выключен.Но тогда средство проверки типов все еще преследует свой собственный хвост, пытаясь доказать, что ограничение выполнимо.Только с подъемным экземпляром это невозможно.Если вы предоставите привязку, то сможете.

Но обеспечить подпись типа намного лучше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...