2016-06-13 18 views
8

İstediğim böyle bir şey yazmaktırControl.Arrow: Neden "(a, b) = (ilk, saniye)" izin verir "başarısız? Ben bile yazamıyorum öğrendim</p> <p><code>let (a,b) = if *condition* then (first, second) else (second, first)</code></p> <p>:

let (a,b) = (first,second)

Bir hata ile başarısız:

<interactive>:7:5:                               
Could not deduce (Arrow a0)                            
from the context (Arrow a) 
    bound by the inferred type for `a': 
      Arrow a => a b c -> a (b, d) (c, d) 
    at <interactive>:7:5-26 
The type variable `a0' is ambiguous 
When checking that `a' has the inferred type 
    a :: forall (a :: * -> * -> *) b c d. 
     Arrow a => 
     a b c -> a (b, d) (c, d) 
Probable cause: the inferred type is ambiguous 

<interactive>:7:5: 
Could not deduce (Arrow a0) 
from the context (Arrow a) 
    bound by the inferred type for `b': 
      Arrow a => a b c -> a (d, b) (d, c) 
    at <interactive>:7:5-26 
The type variable `a0' is ambiguous 
When checking that `b' has the inferred type 
    b :: forall (a :: * -> * -> *) b c d. 
     Arrow a => 
     a b c -> a (d, b) (d, c) 
Probable cause: the inferred type is ambiguous 
+5

Simon Peyton-Jones (şimdi bulmakta zorluk yaşıyorum) posta listeleri birine büyük bir e-posta var gibi typechecking desen bağlamaları inceliklerini ele hangi bu. Gerçekten de, Haskell98 Raporunun konuyu tamamen gözden kaçırdığı ve komitenin Haskell 2010 Raporu'nu yazmadan önce desen bağlamaları için nasıl bir yazım denetimi yapılması gerektiği konusunda biraz zaman harcadığı çok ince. Ben bir cevap yazabilirim, ancak SPJ'nin önündeki e-postaları almadan inceliklerini almak için kendime güvenmeme gerek yok ... –

+0

Bir tahminde, sorun şu ki, bağın sağ tarafı, çıkarsama türünü alır. a1 a2. (Ok a1, Ok a2) => (a1 ..., a2 ...) 'yerine (forall a1. Ok a1 => ..., forall a2. Ok a2 => ...)', bu yüzden forall, tuple * in * dışına taşınır ve çiftdeki değerlerin her ikisi de tamamen polimorfik değildir. –

cevap

2

Çok kısa bir süre, sen Impredicative türünü oluşturmak için çalıştıkları GHC çıkamaz.

λ Control.Arrow > let (a,b) = (first, second) :: Arrow a => (a b b -> a (b, b) (b, b), a b b -> a (b, b) (b, b)) 
λ Control.Arrow > :t a 
a :: Arrow a => a b b -> a (b, b) (b, b) 
λ Control.Arrow > :t b 
b :: Arrow a => a b b -> a (b, b) (b, b) 

veya

:set -XImpredicativeTypes 
λ Control.Arrow > let (a,b) = (first, second) :: (Arrow a => a b b -> a (b, b) (b, b), Arrow a => a b b -> a (b, b) (b, b)) 
λ Control.Arrow > :t a 
a :: Arrow a => a b b -> a (b, b) (b, b) 
λ Control.Arrow > :t b 
b :: Arrow a => a b b -> a (b, b) (b, b) 

ama yapamayacağınız: Yapabileceğiniz

λ Control.Arrow > let (a,b) = (first, second) :: (Arrow a, Arrow a') => (a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b)) 

sorunu ayırmak için, bu işleri:

λ Control.Arrow > let p = (first, second) :: (Arrow a, Arrow a') => (a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b)); 
λ Control.Arrow > :t p 
p :: (Arrow a', Arrow a) => 
    (a b b -> a (b, b) (b, b), a' b b -> a' (b, b) (b, b)) 

ancak desen o bağlamak çalıştığınızda:

λ Control.Arrow > let (a, b) = p 

başarısız. Kısıtlamalar

λ Control.Arrow > :set -XImpredicativeTypes 
λ Control.Arrow > let p = (first, second) :: (Arrow a => a b b -> a (b, b) (b, b), Arrow a => a b b -> a (b, b) (b, b)) 
λ Control.Arrow > let (a, b) = p 

eserler olarak, çift tipli dışındaysanız ve çiftin diğer yarısı için gereksizdir.


Basit bir örnek:

λ Prelude Data.Monoid > :t (mappend,()) 
(mappend,()) :: Monoid a => (a -> a -> a,()) 
λ Prelude Data.Monoid > let (a, b) = (mappend,()) 

<interactive>:12:5: 
    No instance for (Monoid a0) 
     arising from the ambiguity check for ‘b’ 
    The type variable ‘a0’ is ambiguous 
    When checking that ‘b’ has the inferred type ‘()’ 
    Probable cause: the inferred type is ambiguous 

bir kısıtlamaları üzerinden taşımak için, ancak diğer bir deyişle Monoid a =>() kuşkulu türüdür () tipi açısından a yoktur.


Not: let (a,b) = ((+), (*)) çalışıyor görünüyor.Hiçbir fikrim yok neden ve nasıl Num özel olarak ele alındığından:

λ Prelude Data.Monoid > let x =() :: Num a =>() 
λ Prelude Data.Monoid > :t x 
x ::() 
λ Prelude Data.Monoid > let x =() :: Monoid m =>() 

<interactive>:12:9: 
    No instance for (Monoid m0) 
    ... 
1
monomorphism restriction kullanıyorsunuz. Bu sadece Haskell'in tür çıkarımının bir sınırlamasıdır ve açık bir tip imzası ekleyerek çevreyi aşabilirsiniz.

import Control.Arrow 

foo :: (Arrow a, Arrow a1) => (a b c -> a (b, d) (c, d), a1 b1 c1 -> a1 (d1, b1) (d1, c1)) 
foo = (first, second) 

Bu kod foo için tür imzası ile ince typechecks ama bunu kaldırırsanız o "belirsiz değişken" derleme hatası veriyor.

BTW, kullandığım tür imzası, GHCI'de :t (first, second) tarafından çıkarılan bir imzadır. Eğer aynı tür olması (first, second) ve (second, first) istediğim için, muhtemelen böyle aşağıdaki biri olarak, Ek açıklamanızda daha belirli bir türü kullanmak isteyeceklerdir:

foo :: (Arrow a) => (a b b -> a (b, b) (b, b), a b b -> a (b, b) (b, b)) 
+1

O (a, b) = ... 'değil, foo = ...' dır, bu da fark yaratır. Bu monomorfizm kısıtlaması değildir. Kapat ve kendin gör. Bunu yapmadığınızı garanti edebilirim, çünkü gönderdiğiniz kodun doğru içe aktarma bile yoktur. –

+0

@DanielWagner: İthal için üzgünüm. Bu sadece bir yazım hatası ve aslında koşuyordu kodu doğru "Control.Arrow" üstte tüm üstte vardı :) – hugomg

+3

Yine de, yükselttiğim diğer itiraz nedeniyle cevabınız yanlış: '(a, b) = ... 've' foo = ... 'aynı davranmazlar. –