2017-11-03 3 views
7

Im folgenden Code kann GHC die Funktor-Instanz in der Definition der Monoidal Instanz nicht finden.Superklasse kann nicht abgeleitet werden

Warum nicht GHC herzuleiten, dass gegeben die Applicative Einschränkung erfüllt ist, dann ist die Functorhat irgendwo schon zu sein? (Gibt es einen Namen zu dieser Argumentation ‚Fähigkeit‘?)

import Prelude hiding (Applicative (..), Monad (..)) 

class Functor f => Applicative f where 
    pure :: a -> f a 
    (<*>) :: f (a -> b) -> f a -> f b 

class Functor f => Monoidal f where 
    unit::f() 
    (*) ::f a -> f b -> f (a,b) 

instance Applicative f => Monoidal f where 
    unit = pure() 
    a * b = undefined 

Ich weiß natürlich könnte eine explizite Functor f Einschränkung Monoidal Fügen Sie nicht den Fehler haben, aber meine Frage ist, mehr darüber, warum funktioniert Instanz Auflösung auf diese Weise

import Prelude hiding ((*), Applicative (..), Monad (..)) 

class Functor f => Applicative f where 
    pure :: a -> f a 
    (<*>) :: f (a -> b) -> f a -> f b 

class Functor f => Monoidal f where 
    unit::f() 
    (*) ::f a -> f b -> f (a,b) 

instance (Applicative f, Functor f) => Monoidal f where 
    unit = pure() 
    a * b = (pure (,) <*> a <*> b) 

instance (Monoidal f, Functor f) => Applicative f where 
    pure x = fmap (\_ -> x) unit 
    mu <*> mx = fmap (\(f, x) -> f x) ((mu * mx) :: f (a -> b, a)) 
+2

Ich hoffe, es ist klar, dass eine solche Instanz nicht viel Sinn macht! - Trotzdem, gute Frage, ich hätte auch den Compiler angenommen, dies zuzulassen und die Superklasse herauszufinden. – leftaroundabout

+0

Das Grundproblem, das ich sehe, ist, dass Sie sowohl "Functor f => Monoidal f" und "Applicative f => Monoidal f" haben. Wie ich es verstehe, muss der Compiler nur einen möglichen Ableitungspfad für eine bestimmte Typklasse auf einem bestimmten Typ sehen. – NovaDenizen

+0

@leftaroundabout, weil es ein Isomorphismus ist hin und her ist das, was du meinst? deshalb legte ich die iso, um daran erinnert zu werden – nicolas

Antwort

3

Sieht aus wie ein Fehler für mich. Hier ist eine minimale Datei, die das Problem zeigt und nicht auf irgendwelche Spielereien mit Umbenennung Prelude Zeug oder undefined s.

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE UndecidableInstances #-} 
class A x 
class A x => B x 
class A x => C x 
instance B x => C x 

Ich empfehle einen Fehler auf dem GHC-Bug-Tracker mit dieser Datei (oder einer sehr ähnlich); die Begründung, die benötigt wird, um zu entdecken, dass B x impliziert A x sollte möglich sein.

+1

Ich habe dies als [TraC# 14417] (https://ghc.haskell.org/trac/ghc/ticket/14417) – dfeuer

+0

gemeldet und es stellte sich heraus bekannt und offiziell erwartetes Verhalten ab 8.0. Seltsam. – dfeuer

+2

Und [dieser Kommentar] (https://ghc.haskell.org/trac/ghc/ticket/11427#comment:4) scheint der Geldschuss zu sein, der das Problem erklärt, das durch dieses Verhalten gelöst wird. Es ist jedoch ziemlich technisch. –

Verwandte Themen