2010-01-31 33 views
36

Ben GHCi içinde aşağıdakileri yapın:Haskell Belirsiz Geçişler - nasıl önlenir?

:m + Data.Map 
let map = fromList [(1, 2)] 
lookup 1 map 

GHCI O haritayı bilen bir (Harita Tamsayı Tamsayı). Öyleyse, neden net olduğunda Prelude.lookup ve Data.Map.lookup arasında bir belirsizlik olduğunu ve neden önlenebilir?

<interactive>:1:0: 
    Ambiguous occurrence `lookup' 
    It could refer to either `Prelude.lookup', imported from Prelude 
          or `Data.Map.lookup', imported from Data.Map 

> :t map 
map :: Map Integer Integer 
> :t Prelude.lookup 
Prelude.lookup :: (Eq a) => a -> [(a, b)] -> Maybe b 
> :t Data.Map.lookup 
Data.Map.lookup :: (Ord k) => k -> Map k a -> Maybe a 

cevap

46

türleri açıkça farklıdır ama Haskell isimlerin ad-hoc aşırı yüklenmesini izin vermez, bu nedenle sadece bir lookup bir önek olmaksızın kullanılabilecek tercih edebilirsiniz. ,

Sonra
> import qualified Data.Map as Map 

Genelde

> lookup 1 [(1,2), (3,4)] 
Just 2 
> Map.lookup 1 Map.empty 
Nothing 

söyleyebiliriz Haskell kütüphaneleri ya yeniden kullanarak Prelude gelen isimleri, ya da başka yeniden kullanımını önlemek:

tipik çözüm Data.Map nitelikli ithal etmektir Onlardan bir demet. Data.Map, ikincisinden biridir ve yazarlar bunu nitelikli olarak almanızı bekliyor.

[düzenle ephemient yorumuna dahil etmek] Eğer öneki olmadan Data.Map.lookup kullanmak istiyorsanız dolaylı aksi aktardıktan beri, sen Prelude.lookup gizlemek zorunda

: Bu biraz garip ama belki

import Prelude hiding (lookup) 
import Data.Map (lookup) 

Data.Map.lookup'u bir bütün halinde kullanırsanız ve veri yapılarınız tümüyle haritalandırılırsa, hiçbir zaman aldatıcı olmamanız durumunda yararlı olur. Bu ilk başta beni karıştı şey

biraz daha genel not
18

- yani, bana Nathan Sanders yinelemek ve bir şeyler vurgulamak izin söyledi:

Haskell isimlerin ad-hoc aşırı yüklenmesini izin vermez

Bu, varsayılan olarak doğrudur, ancak ilk bakışta şaşırtıcı olmayan bir şekilde görünüyor. Haskell sağlar polymorphic functions iki tarzı: bir fonksiyon, yapısal olarak, özet bir şekilde rasgele tipleri üzerinde çalışmasına olanak sağlar

  • Parametrik polimorfizmi,
  • bir işlev çalışmasına olanak sağlar Ad-hoc polimorfizm, umut verici bir biçimde tanımlanmış bir yapısal olarak farklı olarak tip grubu, ancak, Haskell'e bir semantik Parametrik polimorfizm standart

aynı şekilde (ve tercih edilen bir seçenek sunulur) yaklaşımı herhangi bir ilgili diller; Ad-hoc polimorfizmi diğer birçok dilde standarttır, "fonksiyon aşırı yüklenmesi" gibi isimlerle başlar ve genellikle aynı isimle birden fazla fonksiyon yazarak pratikte uygulanır.

Geçici polimorfizmi ilişkili ad-hoc polimorfik tüm fonksiyonlarında azalmaya tanımlanacak sınıfı gerektiren tip sınıfları tarafından Haskell etkindir ve örnekler açıkça aşırı yük çözünürlükte kullandığı türleri için ilan edilecek.Örnek bildiriminin dışında tanımlanan işlevler, türlerinin bir referansın net olmayacağı kadar farklı olsalar bile, hiçbir zaman geçici polimorfik olmayan'dur.

Bu nedenle, farklı modüllerde aynı ada sahip çok sayıda sınıf dışı işlev tanımlandığında, her iki modemi de modifiye etmek için her iki modemi de almanız hatalarla sonuçlanacaktır. Bu bağlamda özellikle Data.List, Data.Map ve Data.Set arasındaki kombinasyonlar özellikle uygundur ve Data.List'un parçaları Prelude tarafından ihraç edildiği için, standart uygulama (Nathan Sanders'in dediği gibi) her zaman diğerlerini nitelikli olarak içe aktarmak içindir.

+0

Aradığım cevap bu, +1. Ama bir sorum var. Neden, tüm bu 'Data.List',' Data.Set' vb. Ya da varsa (ve eğer doğru bir şekilde anlarsam, bu 'Functor' tipinde bir yazım hatasıdır) - o zaman, örneklerini konteyner türleri için tanımlama neden kütüphanelerde her yerde bulunmuyor? – ulidtko

+0

@ulidtko: Kısa cevap “çünkü kulağa çok daha zor geliyor” ve uzun cevap bir yoruma uymuyordu. Konteynırların hangi tip işlemleri desteklediğine ve eleman tipleri üzerinde hangi sınırlamalara sahip olduğuna dair pek çok karışıklık vardır, & c. 'TypeFamilies' uzantısıyla ilgili bilgilere bakın - container API'leri bunun için motive edici bir örnektir. –

+3

@ulidtko Bu sizin için ilginç olabilir: http://hackage.haskell.org/packages/archive/classy-prelude/0.4.1/doc/html/ClassyPrelude.html –

İlgili konular