Temel kural, FP programlama fonksiyonlarında OO-programlamada nesnelerle aynı işi yapmaktır. Yöntemlerini çağırabilirsiniz (yine de "call" yöntemi) ve bazı kapsüllenmiş iç kurallara göre yanıt verirler. Özellikle, her nezih FP dili, fonksiyonlarınızda kapanış / sözcüksel kapsam belirleme ile "örnek değişkenleri" olmasını sağlar.
var make_OO_style_counter = function(){
return {
counter: 0
increment: function(){
this.counter += 1
return this.counter;
}
}
};
var make_FP_style_counter = function(){
var counter = 0;
return fucntion(){
counter += 1
return counter;
}
};
Şimdi bir sonraki soru bir arayüzle ne demek istiyorsun? Bir yaklaşım nominal arayüzler kullanmaktır (bunu söylüyorsa arayüze uygundur) - bu genellikle hangi dili kullandığınıza çok bağlıdır, bu yüzden ikinci dil için bırakın. Bir arayüz tanımlamanın diğer yolu, bir şeyin hangi parametreleri aldığını ve geri döndüğünü görerek yapısal yöntemdir. Bu, dinamik, ördek tipi dillerde görmeye meyilli olduğunuz bir arayüz türüdür ve tüm FP'lere çok uygundur: bir arayüz sadece fonksiyonlarımıza giriş parametrelerinin türleri ve geri döndükleri türlerdir, böylece tüm fonksiyonlar doğru tipler arayüze uygun!
Bu nedenle, bir arabirimle eşleşen bir nesneyi temsil etmenin en basit yolu, basitçe bir grup işleve sahip olmaktır. Genellikle işlevleri bir tür kayıtta paketleyerek ayrı ayrı geçirmenin çirkinliğini giderirsiniz:
var my_blarfable = {
get_name: function(){ ... },
set_name: function(){ ... },
get_id: function(){ ... }
}
do_something(my_blarfable)
Çıplak işlevlerin veya işlev kayıtlarının kullanılması, tonlarca kazan plakası olmadan yaygın sorunlarınızın çoğunu "yağsız" bir şekilde çözmede uzun bir yol kat edecektir. Bundan daha gelişmiş bir şeye ihtiyacınız varsa, bazen diller size ekstra özellikler sağlar. İnsanların bahsettiği örneklerden biri Haskell tipi sınıflardır. Tür sınıfları, bir türü temel olarak bu işlev kayıtlarından biriyle ilişkilendirir ve sözlükler örtük olması ve iç işlevlere uygun şekilde otomatik olarak aktarılması için bir şeyler yazmanıza olanak tanır.
-- Explicit dictionary version
-- no setters because haskell doesn't like mutable state.
data BlargDict = BlargDict {
blarg_name :: String,
blarg_id :: Integer
}
do_something :: BlargDict -> IO()
do_something blarg_dict = do
print (blarg_name blarg_dict)
print (blarg_id blarg_dict)
-- Typeclass version
class Blargable a where
blag_name :: a -> String
blag_id :: a -> String
do_something :: Blargable a => a -> IO
do_something blarg = do
print (blarg_name blarg)
print (blarg_id blarg)
Bununla birlikte, tipler hakkında not edilmesi gereken önemli bir nokta, sözlüklerin değerlerle değil türlerle ilişkili olmasıdır (sözlükte ve OO sürümlerinde olduğu gibi). Bu, yazı sisteminin "türleri" karıştırmanıza izin vermediği anlamına gelir [1]. Bir "blargables" listesi veya blargables alan bir ikili fonksiyon istiyorsanız, sözlük yaklaşımı farklı türlerden blargable'lara sahip olmanıza izin verirken, tipler her şeyin aynı tipte olmasını sağlar (hangi sürüm daha iyi olduğunuza çok bağlıdır. ) yapıyor
[1] "Varoluşçu Tipler" i yapmanın gelişmiş yolları vardır, ancak genellikle sorun yaratmaya değmez.