2017-11-03 70 views
7

'dan çıkarılamıyor Aşağıdaki kodda, GHC, Funer örneğini Monoidal örneğinin tanımında bulamıyor.Superclass

Neden GHC Applicative kısıt sonra Functor yerde zaten olmalı, memnun verilen bu deducing değil?

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 

Tabii hata olmadığı için Monoidal için açık Functor f kısıtlama eklemek biliyorum, ama benim sorum örneği çözünürlüğü bu şekilde çalışır neden daha fazla olduğunu (bu akıl 'yetenek'? Bir isim yoktur)

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

Umarım böyle bir durumun çok anlamlı olmadığı açıktır! - Yine de iyi bir soru, derleyiciye buna izin vermeyi ve süper sınıfı anlamaya da karar verdim. – leftaroundabout

+0

Gördüğüm temel sorun, "Functor f => Monoidal f" ve "Applicative f => Monoidal f" 'ya sahip olmanızdır. Anladığım kadarıyla, derleyici belirli bir türdeki belirli bir yazım için yalnızca bir olası türev yolunu görmelidir. – NovaDenizen

+0

@leftaroundabout, çünkü bir izomorfizm, ileri geri demek oluyor? İşte bu yüzden, ben bu izolatı – nicolas

cevap

3

Bana bir hata gibi görünüyor. İşte sorunu gösteren ve Prelude veya undefined s renaming ile herhangi bir shenanigans güvenmiyor minimal bir dosyadır.

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

Bu dosyayla GHC hata izleyicide bir hatayı dosyalamanızı öneririz (ya da benzeri); B x'un A x anlamına geldiğinin anlaşılması için gerekçelendirme mümkün olmalıdır.

+1

hatırlatmak için [TraC# 14417] (https://ghc.haskell.org/trac/ghc/ticket/14417) – dfeuer

+0

olarak bildirdim. Bilinen ve resmi olarak beklenen davranış olarak 8.0. Tuhaf. – dfeuer

+2

Ve [Bu yorum] (https://ghc.haskell.org/trac/ghc/ticket/11427#comment:4) bu davranışla çözülen problemi açıklayan para çekimi gibi görünüyor. Yine de oldukça teknik. Hızlıydı –