SORU
7 EKİM 2010, PERŞEMBE


Haskell uygulama ve tımar işlevi

Her zaman yeni bir dil öğrenmeye ilgi, benim ayak beni tutar ve bana (sanırım) daha iyi bir programcı yapar bu bir gerçek benim. Fetih Haskell benim girişimleri gelip - şimdiye kadar iki defa ve yeniden denemek için zaman olduğuna karar verdi. 3 seferde, değil mi?

Hayır. Ben yeniden okumak eski notlarımı... ve hayal kırıklığı :-(

Kaybetmeme neden olan sorunu inanç geçen sefer kolay oldu: tam sayılar permütasyon. tamsayılar listesi, örneğin, listeler listesi - permütasyon listesi için:

[int] -> [[int]]

Bu aslında genel bir sorun, yerine 'int', 'a', hala geçerli olacak. yukarıda öyle.

Notlar: gelen benim

Ben bunu kendi başıma ilk kod, başarılı olurum. Yaşasın!

Ben göndermek benim çözüm için iyi bir arkadaşım - Haskell guru, genellikle yardımcı olarak alabilirsiniz uzmanları ve yolladı bana, ben söyledim, "ifade ettiği gerçek güç dilini kullanma, genel tesisler için kod gerekiyor". Tüm bunun için, geçenlerde kool-aid, gidelim içti:

permute :: [a] -> [[a]]
permute = foldr (concatMap.ins) [[]]
   where ins x []     = [[x]]
         ins x (y:ys) = (x:y:ys):[ y:res | res <- ins x ys]

Hmm. Bu işe bir son verelim:

bash$ cat b.hs
ins x []     = [[x]]
ins x (y:ys) = (x:y:ys):[ y:res | res <- ins x ys]

bash$ ghci
Prelude> :load b.hs
[1 of 1] Compiling Main             ( b.hs, interpreted )
Ok, modules loaded: Main.

*Main> ins 1 [2,3]
[[1,2,3],[2,1,3],[2,3,1]]

TAMAM, şu ana kadar çok iyi. Bana bir dakika sonra ikinci satırı anlamak için aldı "" ama TAMAM:ins Listedeki tüm olası pozisyonları 1 arg yerleştirir. Serin.

Şimdi, foldr anlamak ve concatMap. "Gerçek dünya", NOKTA anlatıldı... . Haskell

(f . g) x

...olarak, başka bir sentaks

f (g x) 

Ve guru gönderilen kodu, NOKTA foldr, birlikte kullanılan "kat" işlev "çöküş": . ins

*Main> let g=concatMap . ins
*Main> g 1 [[2,3]]
[[1,2,3],[2,1,3],[2,3,1]]

NOKTA guru tarafından nasıl kullanıldığını anlamak istiyorum OK, bu nedenle, eşdeğer ifade NOKTA tanımı, (f . göre çalışacağım g) x = f (g (x) ...

*Main> concatMap (ins 1 [[2,3]])

<interactive>:1:11:
     Couldn't match expected type `a -> [b]'
            against inferred type `[[[t]]]'
     In the first argument of `concatMap', namely `(ins 1 [[2, 3]])'
     In the expression: concatMap (ins 1 [[2, 3]])
     In the definition of `it': it = concatMap (ins 1 [[2, 3]])

!?! Neden? TAMAM, concatMap imzası kontrol ediyorum ve bir lambda ve bir liste ihtiyacı olduğunu bulmak, ama bu sadece insan düşünme, DZD nasıl başa çıkar? NOKTA tanımına göre yukarıda...

(f.g)x = f(g x), 

...yaptığım şey geçerli, bilge değiştirin:

(concatMap . ins) x y = concatMap (ins x y)

Kafasını kaşıyor...

*Main> concatMap (ins 1) [[2,3]]
[[1,2,3],[2,1,3],[2,3,1]]

Yani... NOKTA açıklama görünüşe göre oldu çok basit... NOKTA bir şekilde anlamak için zeki olmak gerekir biz aslında "" "ilk yemek-ed diye uzakta ve almak için" ıns istedim argüman - böylece sadece işletmek isteyen bir işlevi olma [t] (ve "serpmek" '1' tüm olası pozisyonları).

Ama nerede belirtilmiş? Nasıl DZD biz çağrıldığında bunu biliyordu

*Main> (concatMap . ins) 1 [[2,3]]
[[1,2,3],[2,1,3],[2,3,1]]

"İmza bir şekilde bu..." benim ilk argüman "ilkesi? ye iletti eylemleri yaptı

*Main> :info ins
ins :: t -> [t] -> [[t]]        -- Defined at b.hs:1:0-2

Özel bir şey göremiyorum - "" bir alan bir işlevdir'', t ins ''ve bir liste yaratmak için devam"". interspersals t listesi Hiçbir şey "ilk argümanın yemek ve köri away" hakkında.

... Şaşkınım. Anlıyorum (kod bakarak bir saat sonra!) neler oluyor, ama... yüce Tanrım... DZD kaç olabilir görmek için denemeler yapıyor "kapalı"? kabuğu Belki

  let's try with no argument "curried" into "ins",
  oh gosh, boom, 
  let's try with one argument "curried" into "ins",
  yep, works,
  that must be it, proceed)

- Eyvah yine...

Ve her zaman ben zaten biliyorum ne ile öğreniyorum dilleri karşılaştırmak olduğum için, nasıl "ıns" Python bak.

a=[2,3]
print [a[:x] [1] a[x:] for x in xrange(len(a) 1)]

[[1, 2, 3], [2, 1, 3], [2, 3, 1]]

Daha basit olan? dürüst ol...

Yani, biliyorum ben bir acemi olarak Haskell, ama ben kendimi salak gibi... Bakıyorsun 4 satır kod için bir saat, ve biten varsayarak derleyici çalışır... çeşitli yorumlara bulana kadar bir şey bu "tıklama"?

Cehennem silahı alıntı yaparak, "bunun için çok yaşlıyım"...

CEVAP
7 EKİM 2010, PERŞEMBE


(f . g) x = f (g x)

Bu doğrudur. O sizi tamamladı

(f . g) x y = f (g x y)

ayrıca doğru olması gerekir, ama bu durum böyle değil. Aslında, aşağıdakiler doğrudur:

(f . g) x y = f (g x) y

aynı şey değil.

Neden bu doğru mu? İyi (f . g) x y ((f . g) x) y aynı (f . g) x = f (g x) bunu bildiğimiz için yine f (g x) y aynı (f (g x)) y, bunu azaltabiliriz.

(concatMap . ins) 1 [[2,3]] concatMap (ins 1) [[2,3]] eşdeğerdir. Büyü var burada yok.

Bu yaklaşım için başka bir yol türleri)

., concatMap (b -> c) -> (a -> b) -> a -> c*,* 44 45 ** türü vardır bu tip 46 ** türü vardır. Eğer öyleyse biz kullanmak concatMap b -> c değişken ins a -> b tartışma, a olur t, b olur [t] -> [[t]] c olur [[t]] -> [[t]] (x = [t] y = [t]).

Bu yüzden bu tür concatMap . ins t -> [[t]] -> [[t]], yani bir fonksiyonu alarak bir ne ve bir liste listeleri (şey işte) ve geri dönen bir listesi listeleri (aynı tip).

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Adam Washington

    Adam Washing

    12 Mayıs 2006
  • Make:

    Make:

    23 Mart 2006
  • Qmusic Romania

    Qmusic Roman

    8 Temmuz 2011