Aslında, Prelude'da tanımlanan normal bir veri yapıcısıdır. , her modüle otomatik olarak içe aktarılan standart kitaplık olan .
Yapısal Olarak Belki Nedir?
Tanım şuna benzer:
data Maybe a = Just a
| Nothing
Bu bildirim, bir tür Maybe a
değişkeni tarafından parametrelendirilen bir türü tanımlar , bu da a
onu herhangi bir türle yerine kullanabileceğiniz anlamına gelir.a
.
İnşa Etmek ve Yıkmak
Türün iki kurucusu vardır Just a
ve Nothing
. Bir türün birden fazla kurucusu olduğunda, bu, türün bir değerinin olası kuruculardan yalnızca biriyle oluşturulmuş olması gerektiği anlamına gelir. Bu tür için, bir değer ya aracılığıyla oluşturulmuştur Just
ya da Nothing
başka (hatasız) olasılık yoktur.
Yana Nothing
Yapıcı o isimler türde bir üyesi olan bir sabit değer olarak kullanılan zaman, hiçbir parametre türü olan Maybe a
her türlü a
. Fakat Just
yapıcı bir yapıcı olarak kullanıldığında, tip bir işlev gibi hareket araçlarının bir tür parametresi, var a
için Maybe a
yani türü vardır,a -> Maybe a
Dolayısıyla, bir türün kurucuları bu türden bir değer oluşturur; işlerin diğer tarafı, bu değeri kullanmak istediğiniz zamandır ve işte burada kalıp eşleme devreye girer. İşlevlerin aksine, yapıcılar desen bağlama ifadelerinde kullanılabilir ve bu, birden fazla yapıcıya sahip türlere ait değerlerin durum analizini yapmanın yoludur .
Maybe a
Bir kalıp eşleşmesinde bir değer kullanmak için, her kurucu için aşağıdaki gibi bir kalıp sağlamanız gerekir:
case maybeVal of
Nothing -> "There is nothing!"
Just val -> "There is a value, and it is " ++ (show val)
Bu durumda ifadede, değer olsaydı ilk desen eşleşirdi ve değer Nothing
ile oluşturulmuşsa ikincisi eşleşirdi Just
. İkincisi eşleşirse, aynı zamanda adı val
, iletilen parametreye de bağlar .Just
eşleştirdiğiniz değer oluşturulduğunda .
Belki Ne Anlama Gelir
Belki bunun nasıl çalıştığını zaten biliyordunuz; Maybe
değerler için gerçekten bir sihir yoktur , bu sadece normal bir Haskell Cebirsel Veri Türüdür (ADT). Ancak, bir türü, Integer
örneğinizden olduğu gibi, değer Nothing
eksikliğini temsil eden ekstra bir değere ( ) sahip olduğu yeni bir bağlama etkili bir şekilde "yükselttiği" veya genişlettiği için oldukça kullanılır ! Tür sistemi o zaman almak izin önce bu ekstra değer denetlemek gerektirir Integer
o olabilir orada. Bu, dikkate değer sayıda hatayı önler.
Günümüzde pek çok dil, bu tür "değer içermeyen" değerleri NULL referanslar aracılığıyla ele almaktadır. Seçkin bir bilgisayar bilimcisi olan Tony Hoare (Quicksort'u icat etti ve Turing Ödülü sahibi), bunu "milyar dolarlık hatası" olarak kabul ediyor . Belki türü bunu düzeltmenin tek yolu değildir, ancak bunu yapmanın etkili bir yolu olduğu kanıtlanmıştır.
Belki bir Functor olarak
Bir türü diğerine dönüştürme fikri, eski türdeki işlemlerin de yeni tür üzerinde çalışacak şekilde dönüştürülebilmesi fikri Functor
, Maybe a
yararlı bir örneğine sahip olan Haskell türü sınıfının arkasındaki kavramdır .
Functor
fmap
temel türdeki değerlere göre (örneğin Integer
), yükseltilmiş türdeki değerlere göre değişen işlevlere (örneğin ) eşleyen işlevleri eşleyen bir yöntem sağlar Maybe Integer
. Bir değer fmap
üzerinde çalışmak üzere dönüştürülen bir işlev şu şekilde çalışır Maybe
:
case maybeVal of
Nothing -> Nothing -- there is nothing, so just return Nothing
Just val -> Just (f val) -- there is a value, so apply the function to it
Dolayısıyla, bir Maybe Integer
değeriniz m_x
ve bir Int -> Int
fonksiyonunuz f
varsa, gerçekten bir değer alıp almadığına dair endişelenmeden fmap f m_x
fonksiyonu f
doğrudan fonksiyona uygulayabilirsiniz Maybe Integer
. Aslında, değerlere bütün bir kaldırılmış Integer -> Integer
işlevler zinciri uygulayabilirsiniz Maybe Integer
ve Nothing
işiniz bittiğinde yalnızca bir kez açıkça kontrol etme konusunda endişelenmeniz gerekir .
Belki bir Monad olarak
Monad
Henüz a kavramına ne kadar aşina olduğunuzdan emin değilim , ancak en azından daha IO a
önce kullandınız ve yazı tipi imzası ile IO a
oldukça benzer görünüyor Maybe a
. Yapıcılarını IO
size göstermemesi ve bu nedenle yalnızca Haskell çalışma zamanı sistemi tarafından "çalıştırılabilmesi" açısından özel olmasına rağmen , yine de Functor
bir Monad
. Aslında, a'nın bazı ekstra özelliklere sahip Monad
özel bir tür olduğu konusunda önemli bir anlam var Functor
, ancak bu konuya girilecek yer burası değil.
Her neyse, Monadlar IO
eşleme türlerini "değerlerle sonuçlanan hesaplamaları" temsil eden yeni türlere sever ve normal bir işlevi "hesaplamaya dönüştüren ve normal bir işlevi" hesaplamayla sonuçlanan "hesaplamaya dönüştüren Monad
çok benzer bir fmap
işlev aracılığıyla işlevleri türlere kaldırabilirsiniz liftM
. işlevi."
Muhtemelen tahmin etmişsinizdir (şimdiye kadar okuduysanız) bunun Maybe
da bir Monad
. "Bir değer döndürmede başarısız olabilecek hesaplamaları" temsil eder. Aynı fmap
örnekte olduğu gibi , bu, her adımdan sonra hataları açıkça kontrol etmek zorunda kalmadan bir dizi hesaplama yapmanıza olanak tanır. Ve aslında, Monad
örneğin inşa edilme şekli, Maybe
değerlerle ilgili bir hesaplama, bir ile karşılaşıldığı anda dururNothing
, bu nedenle bu, bir hesaplamanın ortasında bir ani iptal veya değersiz bir geri dönüş gibidir.
Belki Yazabilirdin
Daha önce de söylediğim gibi Maybe
, dil sözdizimi veya çalışma zamanı sistemine eklenen türden hiçbir şey yoktur . Haskell bunu varsayılan olarak sağlamadıysa, tüm işlevlerini kendiniz sağlayabilirsiniz! Aslında, onu yine de farklı isimlerle tekrar yazabilir ve aynı işlevselliği elde edebilirsiniz.
Umarım Maybe
türü ve yapıcılarını şimdi anlarsınız , ancak hala net olmayan bir şey varsa, bana bildirin!
Maybe
diğer dillerin kullanılacağı yerlerde kullandığınull
veyanil
(NullPointerException
her köşede kötü sinsice gizlendiği) belirtilmelidir. Şimdi diğer diller de bu yapıyı kullanmaya başlıyor: Scala asOption
ve hatta Java 8 bileOptional
türe sahip olacak .