2016-08-27 18 views
7

(ı çözücü yüzden bu muhtemelen çaylak sorusu olabilir Haskell'ın kısıtlaması iç işleyişini tamamen aşina değilim.)tip uygulamalar ve kısıt türlü

ghc 8.0.1 üzerinde tip uygulamasını kullanmaya çalışıyor gibi aşağıdaki örnek kod bana aşağıdaki hataları veriyor

{-# LANGUAGE KindSignatures, RankNTypes, ConstraintKinds, ScopedTypeVariables, TypeApplications #-} 
module Test where 

import Data.Constraint 

test0 :: forall (b :: *) . (forall a . a -> Bool) -> b -> Bool 
test0 g = g @b 

test1 :: forall (c :: * -> Constraint) (b :: *) . (c b) => (forall a . c a => a -> Bool) -> b -> Bool 
test1 g = g @b 

gösterilen

• Could not deduce: c0 b 
    from the context: c b 
    bound by the type signature for: 
       test1 :: c b => (forall a. c a => a -> Bool) -> b -> Bool 
    at Test.hs:9:10-101 
• In the ambiguity check for ‘test1’ 
    To defer the ambiguity check to use sites, enable AllowAmbiguousTypes 
    In the type signature: 
    test1 :: forall (c :: * -> Constraint) (b :: *). 
      (c b) => (forall a. c a => a -> Bool) -> b -> Bool 

ve

• Could not deduce: c a 
    from the context: c b 
    bound by the type signature for: 
       test1 :: c b => (forall a. c a => a -> Bool) -> b -> Bool 
    at Test.hs:9:10-101 
    or from: c0 a 
    bound by the type signature for: 
       test1 :: c0 a => a -> Bool 
    at Test.hs:9:10-101 
• In the ambiguity check for ‘test1’ 
    To defer the ambiguity check to use sites, enable AllowAmbiguousTypes 
    In the type signature: 
    test1 :: forall (c :: * -> Constraint) (b :: *). 
      (c b) => (forall a. c a => a -> Bool) -> b -> Bool 

test0 hiçbir kısıtlamanın olmadığı yerlerde çalışır, ancak test1 yapmaz.

cevap

6

TypeApplications etkinleştirilmişse, AllowAmbiguousTypes'u da etkinleştirmelisiniz. Bunu yaparsanız, hata gider.

ambiguity checkt tanımlarını reddeder, böylece t :: type ek açıklamasını hiçbir zaman yazamaz. Örneğin: bizim programda başka bir yerde test1 kullanmayı denerseniz

test1 :: Show a => Int 
test1 = 0 

, biz :: açıklama yoluyla Show a kısıtlamayı çözmek için hiçbir yolu yoktur görüyoruz. Bu nedenle, belirsizlik kontrolü tanımın kendisini reddeder.

Elbette, tip uygulamaları ile belirsizlik kontrolü anlamsız hale gelir (muhtemelen, bu durumda varsayılan olarak kapatılmalıdır), çünkü test1 @type, Show type örneğinin bulunduğu her durumda iyi ve tam olarak belirlenir.

Bu, ünlü show . read belirsizlik ile aynı olmadığını unutmayın. Yani hala çok AllowAmbiguousTypes ile bir hata üretir:

test2 = show . read 
-- "ambiguous type variable prevents the constraint from being solved" 

Operasyonel olarak c => t türleriyle değerleri t için c -typed durumlarda sadece fonksiyonlardır. Sadece test1'u tanımlamak iyidir, çünkü her zaman bir sabit işlevi tanımlayabiliriz. Ancak, show . read numaralı belgede örnekleri argüman olarak sunmamız gerekiyor (ya da çalıştırılacak kod yok) ve bunları çözmenin bir yolu yok. Bir tür uygulama olmadan test1 kullanılması benzer şekilde belirsiz olur.