GHCi kullanılırken işlevler için açık tür bildirimleri nasıl sağlanır?


82

GHCi içinde bu işlevin ( Learnyouahaskell'den alınmıştır ) eşdeğerini nasıl tanımlayabilirim ?

import Data.List  

numUniques :: (Eq a) => [a] -> Int  
numUniques = length . nub  

Tür bildirimi olmadan, GHCi işlev tanımını kabul eder, ancak işe yaramaz bir türle sonuçlanır:

Prelude Data.List> import Data.List 
Prelude Data.List> let numUniques' = length . nub
Prelude Data.List> :t numUniques'
numUniques' :: [()] -> Int

Ortaya çıkan işlev, yalnızca bir birim listesini parametre olarak kabul eder.

GHCi'de tür bildirimleri sağlamanın bir yolu var mı? Veya bu gibi işlevleri tanımlamanın tür bildirimleri gerektirmeyen başka bir yolu var mı?

GHCi kılavuzunda açık bir ipucu görmedim ve aşağıdaki gibi ifadeler ile deneyler yaptım (boşuna):

> let numUniques' = ((length . nub) :: (Eq a) => [a] -> Int)
> :t numUniques'
numUniques' :: [()] -> Int

Yanıtlar:


101

GHCi'de tür bildirimleri sağlamanın bir yolu var mı?

let numUniques' :: (Eq a) => [a] -> Int; numUniques' = length . nub

Veya bu gibi işlevleri tanımlamanın tür bildirimleri gerektirmeyen başka bir yolu var mı?

Monomorfizm kısıtlamasını ile kapatırsanız -XNoMonomorphismRestriction, doğru türü çıkaracaktır.


3
Henüz monomorfizmle orada değilim, ancak genel olarak bu cevap beni GHCi'deki tanımları bir arada gruplandırmak için noktalı virgül kullanmaya işaret etti - öğreticiler bir .hs dosyasında olduğu gibi yazılır, bu da GHCi'de denendiğinde birçok farklı sorun ortaya çıkarır (işlevler bağlamadan yoksundur vb.) .).
Tomasz Gandor

-XNoMonomorphismRestriction
7.8.1'den

13

Ayrıca ifadenize "noktalar" (yani açık değişkenler) ekleyerek de monomorfizm kısıtlamasından kaçınabileceğinizi unutmayın. Bu aynı zamanda doğru türü verir:

numUniques x = uzunluk olsun. nub $ x


1
Teşekkürler - bunu bilmek harika.
mattbh

Bu, eta-genişlemesi olarak bilinir
Bladt

3

GHC Kullanım Kılavuzu, bunu başarmanın iki ek yolunu gösterir. Bu alt bölüm , aşağıdaki gibi kullanılabilen :{... :}yapısını tanıtır :

> :{
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| :}

Alternatif olarak, çok satırlı modu etkinleştirebilirsiniz :

> :set +m
> let
| numUniques :: (Eq a) => [a] -> Int
| numUniques = length . nub
| 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.